HmacSha256Key PeerAuth::getSendingMacKey(Curve25519Public const& remotePublic, uint256 const& localNonce, uint256 const& remoteNonce, Peer::PeerRole role) { std::vector<uint8_t> buf; if (role == Peer::WE_CALLED_REMOTE) { // If WE_CALLED_REMOTE then sending key is K_AB, // and A is local and B is remote. buf.push_back(0); buf.insert(buf.end(), localNonce.begin(), localNonce.end()); buf.insert(buf.end(), remoteNonce.begin(), remoteNonce.end()); } else { // If REMOTE_CALLED_US then sending key is K_BA, // and B is local and A is remote. buf.push_back(1); buf.insert(buf.end(), localNonce.begin(), localNonce.end()); buf.insert(buf.end(), remoteNonce.begin(), remoteNonce.end()); } auto k = getSharedKey(remotePublic, role); return hkdfExpand(k, buf); }
uint256 JoinSplit<NumInputs, NumOutputs>::h_sig( const uint256& randomSeed, const boost::array<uint256, NumInputs>& nullifiers, const uint256& pubKeyHash ) { const unsigned char personalization[crypto_generichash_blake2b_PERSONALBYTES] = {'Z','c','a','s','h','C','o','m','p','u','t','e','h','S','i','g'}; std::vector<unsigned char> block(randomSeed.begin(), randomSeed.end()); for (size_t i = 0; i < NumInputs; i++) { block.insert(block.end(), nullifiers[i].begin(), nullifiers[i].end()); } block.insert(block.end(), pubKeyHash.begin(), pubKeyHash.end()); uint256 output; if (crypto_generichash_blake2b_salt_personal(output.begin(), 32, &block[0], block.size(), NULL, 0, // No key. NULL, // No salt. personalization ) != 0) { throw std::logic_error("hash function failure"); } return output; }
void dumpKeyInfo(uint256 secret) { CKey key; CAnoncoinSecret b58secret; printf(" * secret (hex): %s\n", secret.GetHex().c_str()); for (int nCompressed=0; nCompressed<2; nCompressed++) { bool fCompressed = nCompressed == 1; printf(" * %s:\n", fCompressed ? "compressed" : "uncompressed"); key.Set( secret.begin(), secret.end(), fCompressed ); b58secret.SetKey( key ); printf(" * secret (base58): %s\n", b58secret.ToString().c_str()); CPubKey pubkey = key.GetPubKey(); printf(" * address (base58): %s\n", CAnoncoinAddress(CTxDestination(pubkey.GetID())).ToString().c_str() ); } }
void CAuxPow::initAuxPow (CBlockHeader& header) { /* Set auxpow flag right now, since we take the block hash below. */ header.SetAuxpowVersion(true); /* Build a minimal coinbase script input for merge-mining. */ const uint256 blockHash = header.GetHash (); valtype inputData(blockHash.begin (), blockHash.end ()); std::reverse (inputData.begin (), inputData.end ()); inputData.push_back (1); inputData.insert (inputData.end (), 7, 0); /* Fake a parent-block coinbase with just the required input script and no outputs. */ CMutableTransaction coinbase; coinbase.vin.resize (1); coinbase.vin[0].prevout.SetNull (); coinbase.vin[0].scriptSig = (CScript () << inputData); assert (coinbase.vout.empty ()); CTransactionRef coinbaseRef = MakeTransactionRef (coinbase); /* Build a fake parent block with the coinbase. */ CBlock parent; parent.nVersion = 1; parent.vtx.resize (1); parent.vtx[0] = coinbaseRef; parent.hashMerkleRoot = BlockMerkleRoot (parent); /* Construct the auxpow object. */ header.SetAuxpow (new CAuxPow (coinbaseRef)); assert (header.auxpow->vChainMerkleBranch.empty ()); header.auxpow->nChainIndex = 0; assert (header.auxpow->vMerkleBranch.empty ()); header.auxpow->nIndex = 0; header.auxpow->parentBlock = parent; }
std::uint64_t getQuality (uint256 const& uBase) { // VFALCO [base_uint] This assumes a certain storage format return be64toh (((std::uint64_t*) uBase.end ())[-1]); }
bool CAuxPow::check (const uint256& hashAuxBlock, int nChainId, const Consensus::Params& params) const { if (nIndex != 0) return error("AuxPow is not a generate"); if (params.fStrictChainId && parentBlock.GetChainId () == nChainId) return error("Aux POW parent has our chain ID"); if (vChainMerkleBranch.size() > 30) return error("Aux POW chain merkle branch too long"); // Check that the chain merkle root is in the coinbase const uint256 nRootHash = CheckMerkleBranch (hashAuxBlock, vChainMerkleBranch, nChainIndex); valtype vchRootHash(nRootHash.begin (), nRootHash.end ()); std::reverse (vchRootHash.begin (), vchRootHash.end ()); // correct endian // Check that we are in the parent block merkle tree if (CheckMerkleBranch(GetHash(), vMerkleBranch, nIndex) != parentBlock.hashMerkleRoot) return error("Aux POW merkle root incorrect"); const CScript script = tx->vin[0].scriptSig; // Check that the same work is not submitted twice to our chain. // CScript::const_iterator pcHead = std::search(script.begin(), script.end(), UBEGIN(pchMergedMiningHeader), UEND(pchMergedMiningHeader)); CScript::const_iterator pc = std::search(script.begin(), script.end(), vchRootHash.begin(), vchRootHash.end()); if (pc == script.end()) return error("Aux POW missing chain merkle root in parent coinbase"); if (pcHead != script.end()) { // Enforce only one chain merkle root by checking that a single instance of the merged // mining header exists just before. if (script.end() != std::search(pcHead + 1, script.end(), UBEGIN(pchMergedMiningHeader), UEND(pchMergedMiningHeader))) return error("Multiple merged mining headers in coinbase"); if (pcHead + sizeof(pchMergedMiningHeader) != pc) return error("Merged mining header is not just before chain merkle root"); } else { // For backward compatibility. // Enforce only one chain merkle root by checking that it starts early in the coinbase. // 8-12 bytes are enough to encode extraNonce and nBits. if (pc - script.begin() > 20) return error("Aux POW chain merkle root must start in the first 20 bytes of the parent coinbase"); } // Ensure we are at a deterministic point in the merkle leaves by hashing // a nonce and our chain ID and comparing to the index. pc += vchRootHash.size(); if (script.end() - pc < 8) return error("Aux POW missing chain merkle tree size and nonce in parent coinbase"); uint32_t nSize; memcpy(&nSize, &pc[0], 4); nSize = le32toh (nSize); const unsigned merkleHeight = vChainMerkleBranch.size (); if (nSize != (1u << merkleHeight)) return error("Aux POW merkle branch size does not match parent coinbase"); uint32_t nNonce; memcpy(&nNonce, &pc[4], 4); nNonce = le32toh (nNonce); if (nChainIndex != getExpectedIndex (nNonce, nChainId, merkleHeight)) return error("Aux POW wrong index"); return true; }