// Look up the master public generator for a regular seed so we may index source accounts ids. // --> naRegularSeed // <-- naMasterGenerator Json::Value getMasterGenerator ( Ledger::ref lrLedger, const RippleAddress& naRegularSeed, RippleAddress& naMasterGenerator, NetworkOPs& netOps) { RippleAddress na0Public; // To find the generator's index. RippleAddress na0Private; // To decrypt the master generator's cipher. RippleAddress naGenerator = RippleAddress::createGeneratorPublic (naRegularSeed); na0Public.setAccountPublic (naGenerator, 0); na0Private.setAccountPrivate (naGenerator, naRegularSeed, 0); SLE::pointer sleGen = netOps.getGenerator (lrLedger, na0Public.getAccountID ()); if (!sleGen) { // No account has been claimed or has had it password set for seed. return rpcError (rpcNO_ACCOUNT); } Blob vucCipher = sleGen->getFieldVL (sfGenerator); Blob vucMasterGenerator = na0Private.accountPrivateDecrypt (na0Public, vucCipher); if (vucMasterGenerator.empty ()) { return rpcError (rpcFAIL_GEN_DECRYPT); } naMasterGenerator.setGenerator (vucMasterGenerator); return Json::Value (Json::objectValue); }
Blob RippleAddress::accountPrivateSign (Blob const& message) const { if (vchData.size() == 33 && vchData[0] == 0xED) { uint8_t const* secretKey = &vchData[1]; ed25519_public_key publicKey; Blob signature (sizeof (ed25519_signature)); ed25519_publickey (secretKey, publicKey); ed25519_sign ( message.data(), message.size(), secretKey, publicKey, &signature[0]); assert (isCanonicalEd25519Signature (signature.data())); return signature; } Blob result = ECDSASign( sha512Half(makeSlice(message)), getAccountPrivate()); bool const ok = !result.empty(); CondLog (!ok, lsWARNING, RippleAddress) << "accountPrivateSign: Signing failed."; return result; }
void RippleAddress::signNodePrivate (uint256 const& hash, Blob& vchSig) const { vchSig = ECDSASign (hash, getNodePrivate()); if (vchSig.empty()) Throw<std::runtime_error> ("Signing failed."); }
// create from a base58 encoded seed bool PaysharesPrivateKey::fromString(std::string& base58seed) { Blob vchTemp; Base58::decodeWithCheck(base58seed.c_str(), vchTemp, Base58::getRippleAlphabet()); if (vchTemp.empty() && vchTemp.size() == crypto_sign_SEEDBYTES + 1 && vchTemp[0] == RippleAddress::VER_SEED) { return(false); } mSeed.resize(crypto_sign_SEEDBYTES); memcpy(&mSeed[0], vchTemp.data() + 1, crypto_sign_SEEDBYTES); mPair.setSeed(mSeed); return(true); }
bool CBase58Data::SetString (const char* psz, unsigned char version, Base58::Alphabet const& alphabet) { Blob vchTemp; Base58::decodeWithCheck (psz, vchTemp, alphabet); if (vchTemp.empty () || vchTemp[0] != version) { vchData.clear (); nVersion = 1; return false; } nVersion = vchTemp[0]; vchData.resize (vchTemp.size () - 1); if (!vchData.empty ()) memcpy (&vchData[0], &vchTemp[1], vchData.size ()); memset (&vchTemp[0], 0, vchTemp.size ()); return true; }
Blob PublicKey::encrypt(const Blob& data) const { if (!pk) throw CryptoException("Can't read public key !"); unsigned key_len = 0; int err = gnutls_pubkey_get_pk_algorithm(pk, &key_len); if (err < 0) throw CryptoException("Can't read public key length !"); if (err != GNUTLS_PK_RSA) throw CryptoException("Must be an RSA key"); unsigned max_block_sz = key_len / 8 - 11; unsigned cypher_block_sz = key_len / 8; unsigned block_num = data.empty() ? 1 : 1 + (data.size() - 1) / max_block_sz; Blob ret; auto eb = data.cbegin(); auto ee = data.cend(); for (unsigned i=0; i<block_num; i++) { auto blk_sz = std::min<unsigned>(ee - eb, max_block_sz); const gnutls_datum_t dat {(uint8_t*)&(*eb), blk_sz}; gnutls_datum_t encrypted; err = gnutls_pubkey_encrypt_data(pk, 0, &dat, &encrypted); if (err != GNUTLS_E_SUCCESS) throw CryptoException(std::string("Can't encrypt data: ") + gnutls_strerror(err)); if (encrypted.size != cypher_block_sz) throw CryptoException("Unexpected cypherblock size"); ret.insert(ret.end(), encrypted.data, encrypted.data+encrypted.size); eb += blk_sz; gnutls_free(encrypted.data); } return ret; }
TER AccountSetTransactor::doApply () { WriteLog (lsINFO, AccountSetTransactor) << "AccountSet>"; const uint32 uTxFlags = mTxn.getFlags (); const uint32 uFlagsIn = mTxnAccount->getFieldU32 (sfFlags); uint32 uFlagsOut = uFlagsIn; const uint32 uSetFlag = mTxn.getFieldU32 (sfSetFlag); const uint32 uClearFlag = mTxn.getFieldU32 (sfClearFlag); // legacy AccountSet flags bool bSetRequireDest = (uTxFlags & TxFlag::requireDestTag) || (uSetFlag == asfRequireDest); bool bClearRequireDest = (uTxFlags & tfOptionalDestTag) || (uClearFlag == asfRequireDest); bool bSetRequireAuth = (uTxFlags & tfRequireAuth) || (uSetFlag == asfRequireAuth); bool bClearRequireAuth = (uTxFlags & tfOptionalAuth) || (uClearFlag == asfRequireAuth); bool bSetDisallowXRP = (uTxFlags & tfDisallowXRP) || (uSetFlag == asfDisallowXRP); bool bClearDisallowXRP = (uTxFlags & tfAllowXRP) || (uClearFlag == asfDisallowXRP); if (uTxFlags & tfAccountSetMask) { WriteLog (lsINFO, AccountSetTransactor) << "AccountSet: Malformed transaction: Invalid flags set."; return temINVALID_FLAG; } // // RequireAuth // if (bSetRequireAuth && bClearRequireAuth) { WriteLog (lsINFO, AccountSetTransactor) << "AccountSet: Malformed transaction: Contradictory flags set."; return temINVALID_FLAG; } if (bSetRequireAuth && !isSetBit (uFlagsIn, lsfRequireAuth)) { if (mTxnAccount->getFieldU32 (sfOwnerCount)) { WriteLog (lsINFO, AccountSetTransactor) << "AccountSet: Retry: OwnerCount not zero."; return isSetBit(mParams, tapRETRY) ? terOWNERS : tecOWNERS; } WriteLog (lsINFO, AccountSetTransactor) << "AccountSet: Set RequireAuth."; uFlagsOut |= lsfRequireAuth; } if (bClearRequireAuth && isSetBit (uFlagsIn, lsfRequireAuth)) { WriteLog (lsINFO, AccountSetTransactor) << "AccountSet: Clear RequireAuth."; uFlagsOut &= ~lsfRequireAuth; } // // RequireDestTag // if (bSetRequireDest && bClearRequireDest) { WriteLog (lsINFO, AccountSetTransactor) << "AccountSet: Malformed transaction: Contradictory flags set."; return temINVALID_FLAG; } if (bSetRequireDest && !isSetBit (uFlagsIn, lsfRequireDestTag)) { WriteLog (lsINFO, AccountSetTransactor) << "AccountSet: Set lsfRequireDestTag."; uFlagsOut |= lsfRequireDestTag; } if (bClearRequireDest && isSetBit (uFlagsIn, lsfRequireDestTag)) { WriteLog (lsINFO, AccountSetTransactor) << "AccountSet: Clear lsfRequireDestTag."; uFlagsOut &= ~lsfRequireDestTag; } // // DisallowXRP // if (bSetDisallowXRP && bClearDisallowXRP) { WriteLog (lsINFO, AccountSetTransactor) << "AccountSet: Malformed transaction: Contradictory flags set."; return temINVALID_FLAG; } if (bSetDisallowXRP && !isSetBit (uFlagsIn, lsfDisallowXRP)) { WriteLog (lsINFO, AccountSetTransactor) << "AccountSet: Set lsfDisallowXRP."; uFlagsOut |= lsfDisallowXRP; } if (bClearDisallowXRP && isSetBit (uFlagsIn, lsfDisallowXRP)) { WriteLog (lsINFO, AccountSetTransactor) << "AccountSet: Clear lsfDisallowXRP."; uFlagsOut &= ~lsfDisallowXRP; } // // DisableMaster // if ((uSetFlag == asfDisableMaster) && (uClearFlag == asfDisableMaster)) { WriteLog (lsINFO, AccountSetTransactor) << "AccountSet: Malformed transaction: Contradictory flags set."; return temINVALID_FLAG; } if ((uSetFlag == asfDisableMaster) && !isSetBit (uFlagsIn, lsfDisableMaster)) { if (!mTxnAccount->isFieldPresent (sfRegularKey)) return tecNO_REGULAR_KEY; WriteLog (lsINFO, AccountSetTransactor) << "AccountSet: Set lsfDisableMaster."; uFlagsOut |= lsfDisableMaster; } if ((uClearFlag == asfDisableMaster) && isSetBit (uFlagsIn, lsfDisableMaster)) { WriteLog (lsINFO, AccountSetTransactor) << "AccountSet: Clear lsfDisableMaster."; uFlagsOut &= ~lsfDisableMaster; } // // EmailHash // if (mTxn.isFieldPresent (sfEmailHash)) { uint128 uHash = mTxn.getFieldH128 (sfEmailHash); if (!uHash) { WriteLog (lsINFO, AccountSetTransactor) << "AccountSet: unset email hash"; mTxnAccount->makeFieldAbsent (sfEmailHash); } else { WriteLog (lsINFO, AccountSetTransactor) << "AccountSet: set email hash"; mTxnAccount->setFieldH128 (sfEmailHash, uHash); } } // // WalletLocator // if (mTxn.isFieldPresent (sfWalletLocator)) { uint256 uHash = mTxn.getFieldH256 (sfWalletLocator); if (!uHash) { WriteLog (lsINFO, AccountSetTransactor) << "AccountSet: unset wallet locator"; mTxnAccount->makeFieldAbsent (sfEmailHash); } else { WriteLog (lsINFO, AccountSetTransactor) << "AccountSet: set wallet locator"; mTxnAccount->setFieldH256 (sfWalletLocator, uHash); } } // // MessageKey // if (mTxn.isFieldPresent (sfMessageKey)) { Blob vucPublic = mTxn.getFieldVL (sfMessageKey); if (vucPublic.size () > PUBLIC_BYTES_MAX) { WriteLog (lsINFO, AccountSetTransactor) << "AccountSet: message key too long"; return telBAD_PUBLIC_KEY; } else { WriteLog (lsINFO, AccountSetTransactor) << "AccountSet: set message key"; mTxnAccount->setFieldVL (sfMessageKey, vucPublic); } } // // Domain // if (mTxn.isFieldPresent (sfDomain)) { Blob vucDomain = mTxn.getFieldVL (sfDomain); if (vucDomain.empty ()) { WriteLog (lsINFO, AccountSetTransactor) << "AccountSet: unset domain"; mTxnAccount->makeFieldAbsent (sfDomain); } else if (vucDomain.size () > DOMAIN_BYTES_MAX) { WriteLog (lsINFO, AccountSetTransactor) << "AccountSet: domain too long"; return telBAD_DOMAIN; } else { WriteLog (lsINFO, AccountSetTransactor) << "AccountSet: set domain"; mTxnAccount->setFieldVL (sfDomain, vucDomain); } } // // TransferRate // if (mTxn.isFieldPresent (sfTransferRate)) { uint32 uRate = mTxn.getFieldU32 (sfTransferRate); if (!uRate || uRate == QUALITY_ONE) { WriteLog (lsINFO, AccountSetTransactor) << "AccountSet: unset transfer rate"; mTxnAccount->makeFieldAbsent (sfTransferRate); } else if (uRate > QUALITY_ONE) { WriteLog (lsINFO, AccountSetTransactor) << "AccountSet: set transfer rate"; mTxnAccount->setFieldU32 (sfTransferRate, uRate); } else { WriteLog (lsINFO, AccountSetTransactor) << "AccountSet: bad transfer rate"; return temBAD_TRANSFER_RATE; } } if (uFlagsIn != uFlagsOut) mTxnAccount->setFieldU32 (sfFlags, uFlagsOut); WriteLog (lsINFO, AccountSetTransactor) << "AccountSet<"; return tesSUCCESS; }
// --> strIdent: public key, account ID, or regular seed. // --> bStrict: Only allow account id or public key. // <-- bIndex: true if iIndex > 0 and used the index. Json::Value accountFromString (Ledger::ref lrLedger, RippleAddress& naAccount, bool& bIndex, const std::string& strIdent, const int iIndex, const bool bStrict, NetworkOPs& netOps) { RippleAddress naSeed; if (naAccount.setAccountPublic (strIdent) || naAccount.setAccountID (strIdent)) { // Got the account. bIndex = false; } else if (bStrict) { return naAccount.setAccountID (strIdent, Base58::getBitcoinAlphabet ()) ? rpcError (rpcACT_BITCOIN) : rpcError (rpcACT_MALFORMED); } // Must be a seed. else if (!naSeed.setSeedGeneric (strIdent)) { return rpcError (rpcBAD_SEED); } else { // We allow the use of the seeds to access #0. // This is poor practice and merely for debuging convenience. RippleAddress naRegular0Public; RippleAddress naRegular0Private; RippleAddress naGenerator = RippleAddress::createGeneratorPublic (naSeed); naRegular0Public.setAccountPublic (naGenerator, 0); naRegular0Private.setAccountPrivate (naGenerator, naSeed, 0); // Account uGeneratorID = naRegular0Public.getAccountID(); SLE::pointer sleGen = netOps.getGenerator (lrLedger, naRegular0Public.getAccountID ()); if (!sleGen) { // Didn't find a generator map, assume it is a master generator. } else { // Found master public key. Blob vucCipher = sleGen->getFieldVL (sfGenerator); Blob vucMasterGenerator = naRegular0Private.accountPrivateDecrypt (naRegular0Public, vucCipher); if (vucMasterGenerator.empty ()) { rpcError (rpcNO_GEN_DECRYPT); } naGenerator.setGenerator (vucMasterGenerator); } bIndex = !iIndex; naAccount.setAccountPublic (naGenerator, iIndex); } return Json::Value (Json::objectValue); }
TER doApply () override { std::uint32_t const uTxFlags = mTxn.getFlags (); std::uint32_t const uFlagsIn = mTxnAccount->getFieldU32 (sfFlags); std::uint32_t uFlagsOut = uFlagsIn; std::uint32_t const uSetFlag = mTxn.getFieldU32 (sfSetFlag); std::uint32_t const uClearFlag = mTxn.getFieldU32 (sfClearFlag); if ((uSetFlag != 0) && (uSetFlag == uClearFlag)) { m_journal.trace << "Malformed transaction: Set and clear same flag"; return temINVALID_FLAG; } // legacy AccountSet flags bool bSetRequireDest = (uTxFlags & TxFlag::requireDestTag) || (uSetFlag == asfRequireDest); bool bClearRequireDest = (uTxFlags & tfOptionalDestTag) || (uClearFlag == asfRequireDest); bool bSetRequireAuth = (uTxFlags & tfRequireAuth) || (uSetFlag == asfRequireAuth); bool bClearRequireAuth = (uTxFlags & tfOptionalAuth) || (uClearFlag == asfRequireAuth); bool bSetDisallowXRP = (uTxFlags & tfDisallowXRP) || (uSetFlag == asfDisallowXRP); bool bClearDisallowXRP = (uTxFlags & tfAllowXRP) || (uClearFlag == asfDisallowXRP); if (uTxFlags & tfAccountSetMask) { m_journal.trace << "Malformed transaction: Invalid flags set."; return temINVALID_FLAG; } // // RequireAuth // if (bSetRequireAuth && bClearRequireAuth) { m_journal.trace << "Malformed transaction: Contradictory flags set."; return temINVALID_FLAG; } if (bSetRequireAuth && !(uFlagsIn & lsfRequireAuth)) { if (!mEngine->view().dirIsEmpty (Ledger::getOwnerDirIndex (mTxnAccountID))) { m_journal.trace << "Retry: Owner directory not empty."; return (mParams & tapRETRY) ? terOWNERS : tecOWNERS; } m_journal.trace << "Set RequireAuth."; uFlagsOut |= lsfRequireAuth; } if (bClearRequireAuth && (uFlagsIn & lsfRequireAuth)) { m_journal.trace << "Clear RequireAuth."; uFlagsOut &= ~lsfRequireAuth; } // // RequireDestTag // if (bSetRequireDest && bClearRequireDest) { m_journal.trace << "Malformed transaction: Contradictory flags set."; return temINVALID_FLAG; } if (bSetRequireDest && !(uFlagsIn & lsfRequireDestTag)) { m_journal.trace << "Set lsfRequireDestTag."; uFlagsOut |= lsfRequireDestTag; } if (bClearRequireDest && (uFlagsIn & lsfRequireDestTag)) { m_journal.trace << "Clear lsfRequireDestTag."; uFlagsOut &= ~lsfRequireDestTag; } // // DisallowXRP // if (bSetDisallowXRP && bClearDisallowXRP) { m_journal.trace << "Malformed transaction: Contradictory flags set."; return temINVALID_FLAG; } if (bSetDisallowXRP && !(uFlagsIn & lsfDisallowXRP)) { m_journal.trace << "Set lsfDisallowXRP."; uFlagsOut |= lsfDisallowXRP; } if (bClearDisallowXRP && (uFlagsIn & lsfDisallowXRP)) { m_journal.trace << "Clear lsfDisallowXRP."; uFlagsOut &= ~lsfDisallowXRP; } // // DisableMaster // if ((uSetFlag == asfDisableMaster) && (uClearFlag == asfDisableMaster)) { m_journal.trace << "Malformed transaction: Contradictory flags set."; return temINVALID_FLAG; } if ((uSetFlag == asfDisableMaster) && !(uFlagsIn & lsfDisableMaster)) { if (!mTxnAccount->isFieldPresent (sfRegularKey)) return tecNO_REGULAR_KEY; m_journal.trace << "Set lsfDisableMaster."; uFlagsOut |= lsfDisableMaster; } if ((uClearFlag == asfDisableMaster) && (uFlagsIn & lsfDisableMaster)) { m_journal.trace << "Clear lsfDisableMaster."; uFlagsOut &= ~lsfDisableMaster; } if ((uSetFlag == asfNoFreeze) && (uClearFlag != asfNoFreeze)) { m_journal.trace << "Set NoFreeze flag"; uFlagsOut |= lsfNoFreeze; } // Anyone may set global freeze if ((uSetFlag == asfGlobalFreeze) && (uClearFlag != asfGlobalFreeze)) { m_journal.trace << "Set GlobalFreeze flag"; uFlagsOut |= lsfGlobalFreeze; } // If you have set NoFreeze, you may not clear GlobalFreeze // This prevents those who have set NoFreeze from using // GlobalFreeze strategically. if ((uSetFlag != asfGlobalFreeze) && (uClearFlag == asfGlobalFreeze) && ((uFlagsOut & lsfNoFreeze) == 0)) { m_journal.trace << "Clear GlobalFreeze flag"; uFlagsOut &= ~lsfGlobalFreeze; } // // Track transaction IDs signed by this account in its root // if ((uSetFlag == asfAccountTxnID) && (uClearFlag != asfAccountTxnID) && !mTxnAccount->isFieldPresent (sfAccountTxnID)) { m_journal.trace << "Set AccountTxnID"; mTxnAccount->makeFieldPresent (sfAccountTxnID); } if ((uClearFlag == asfAccountTxnID) && (uSetFlag != asfAccountTxnID) && mTxnAccount->isFieldPresent (sfAccountTxnID)) { m_journal.trace << "Clear AccountTxnID"; mTxnAccount->makeFieldAbsent (sfAccountTxnID); } // // EmailHash // if (mTxn.isFieldPresent (sfEmailHash)) { uint128 uHash = mTxn.getFieldH128 (sfEmailHash); if (!uHash) { m_journal.trace << "unset email hash"; mTxnAccount->makeFieldAbsent (sfEmailHash); } else { m_journal.trace << "set email hash"; mTxnAccount->setFieldH128 (sfEmailHash, uHash); } } // // WalletLocator // if (mTxn.isFieldPresent (sfWalletLocator)) { uint256 uHash = mTxn.getFieldH256 (sfWalletLocator); if (!uHash) { m_journal.trace << "unset wallet locator"; mTxnAccount->makeFieldAbsent (sfWalletLocator); } else { m_journal.trace << "set wallet locator"; mTxnAccount->setFieldH256 (sfWalletLocator, uHash); } } // // MessageKey // if (mTxn.isFieldPresent (sfMessageKey)) { Blob vucPublic = mTxn.getFieldVL (sfMessageKey); if (vucPublic.empty ()) { m_journal.debug << "set message key"; mTxnAccount->makeFieldAbsent (sfMessageKey); } if (vucPublic.size () > PUBLIC_BYTES_MAX) { m_journal.trace << "message key too long"; return telBAD_PUBLIC_KEY; } else { m_journal.debug << "set message key"; mTxnAccount->setFieldVL (sfMessageKey, vucPublic); } } // // Domain // if (mTxn.isFieldPresent (sfDomain)) { Blob vucDomain = mTxn.getFieldVL (sfDomain); if (vucDomain.empty ()) { m_journal.trace << "unset domain"; mTxnAccount->makeFieldAbsent (sfDomain); } else if (vucDomain.size () > DOMAIN_BYTES_MAX) { m_journal.trace << "domain too long"; return telBAD_DOMAIN; } else { m_journal.trace << "set domain"; mTxnAccount->setFieldVL (sfDomain, vucDomain); } } // // TransferRate // if (mTxn.isFieldPresent (sfTransferRate)) { std::uint32_t uRate = mTxn.getFieldU32 (sfTransferRate); if (!uRate || uRate == QUALITY_ONE) { m_journal.trace << "unset transfer rate"; mTxnAccount->makeFieldAbsent (sfTransferRate); } else if (uRate > QUALITY_ONE) { m_journal.trace << "set transfer rate"; mTxnAccount->setFieldU32 (sfTransferRate, uRate); } else { m_journal.trace << "bad transfer rate"; return temBAD_TRANSFER_RATE; } } if (uFlagsIn != uFlagsOut) mTxnAccount->setFieldU32 (sfFlags, uFlagsOut); return tesSUCCESS; }
TER SetAccount::doApply () { std::uint32_t const uTxFlags = ctx_.tx.getFlags (); auto const sle = view().peek( keylet::account(account_)); std::uint32_t const uFlagsIn = sle->getFieldU32 (sfFlags); std::uint32_t uFlagsOut = uFlagsIn; std::uint32_t const uSetFlag = ctx_.tx.getFieldU32 (sfSetFlag); std::uint32_t const uClearFlag = ctx_.tx.getFieldU32 (sfClearFlag); // legacy AccountSet flags bool bSetRequireDest = (uTxFlags & TxFlag::requireDestTag) || (uSetFlag == asfRequireDest); bool bClearRequireDest = (uTxFlags & tfOptionalDestTag) || (uClearFlag == asfRequireDest); bool bSetRequireAuth = (uTxFlags & tfRequireAuth) || (uSetFlag == asfRequireAuth); bool bClearRequireAuth = (uTxFlags & tfOptionalAuth) || (uClearFlag == asfRequireAuth); bool bSetDisallowXRP = (uTxFlags & tfDisallowXRP) || (uSetFlag == asfDisallowXRP); bool bClearDisallowXRP = (uTxFlags & tfAllowXRP) || (uClearFlag == asfDisallowXRP); bool sigWithMaster = false; { auto const blob = ctx_.tx.getSigningPubKey(); if (!blob.empty ()) { auto const signingPubKey = RippleAddress::createAccountPublic(blob); if (calcAccountID(signingPubKey) == account_) sigWithMaster = true; } } // // RequireAuth // if (bSetRequireAuth && !(uFlagsIn & lsfRequireAuth)) { j_.trace << "Set RequireAuth."; uFlagsOut |= lsfRequireAuth; } if (bClearRequireAuth && (uFlagsIn & lsfRequireAuth)) { j_.trace << "Clear RequireAuth."; uFlagsOut &= ~lsfRequireAuth; } // // RequireDestTag // if (bSetRequireDest && !(uFlagsIn & lsfRequireDestTag)) { j_.trace << "Set lsfRequireDestTag."; uFlagsOut |= lsfRequireDestTag; } if (bClearRequireDest && (uFlagsIn & lsfRequireDestTag)) { j_.trace << "Clear lsfRequireDestTag."; uFlagsOut &= ~lsfRequireDestTag; } // // DisallowXRP // if (bSetDisallowXRP && !(uFlagsIn & lsfDisallowXRP)) { j_.trace << "Set lsfDisallowXRP."; uFlagsOut |= lsfDisallowXRP; } if (bClearDisallowXRP && (uFlagsIn & lsfDisallowXRP)) { j_.trace << "Clear lsfDisallowXRP."; uFlagsOut &= ~lsfDisallowXRP; } // // DisableMaster // if ((uSetFlag == asfDisableMaster) && !(uFlagsIn & lsfDisableMaster)) { if (!sigWithMaster) { j_.trace << "Must use master key to disable master key."; return tecNEED_MASTER_KEY; } if ((!sle->isFieldPresent (sfRegularKey)) && (!view().peek (keylet::signers (account_)))) { // Account has no regular key or multi-signer signer list. // Prevent transaction changes until we're ready. if (view().rules().enabled(featureMultiSign, ctx_.app.config().features)) return tecNO_ALTERNATIVE_KEY; return tecNO_REGULAR_KEY; } j_.trace << "Set lsfDisableMaster."; uFlagsOut |= lsfDisableMaster; } if ((uClearFlag == asfDisableMaster) && (uFlagsIn & lsfDisableMaster)) { j_.trace << "Clear lsfDisableMaster."; uFlagsOut &= ~lsfDisableMaster; } // // DefaultRipple // if (uSetFlag == asfDefaultRipple) { uFlagsOut |= lsfDefaultRipple; } else if (uClearFlag == asfDefaultRipple) { uFlagsOut &= ~lsfDefaultRipple; } // // NoFreeze // if (uSetFlag == asfNoFreeze) { if (!sigWithMaster && !(uFlagsIn & lsfDisableMaster)) { j_.trace << "Can't use regular key to set NoFreeze."; return tecNEED_MASTER_KEY; } j_.trace << "Set NoFreeze flag"; uFlagsOut |= lsfNoFreeze; } // Anyone may set global freeze if (uSetFlag == asfGlobalFreeze) { j_.trace << "Set GlobalFreeze flag"; uFlagsOut |= lsfGlobalFreeze; } // If you have set NoFreeze, you may not clear GlobalFreeze // This prevents those who have set NoFreeze from using // GlobalFreeze strategically. if ((uSetFlag != asfGlobalFreeze) && (uClearFlag == asfGlobalFreeze) && ((uFlagsOut & lsfNoFreeze) == 0)) { j_.trace << "Clear GlobalFreeze flag"; uFlagsOut &= ~lsfGlobalFreeze; } // // Track transaction IDs signed by this account in its root // if ((uSetFlag == asfAccountTxnID) && !sle->isFieldPresent (sfAccountTxnID)) { j_.trace << "Set AccountTxnID"; sle->makeFieldPresent (sfAccountTxnID); } if ((uClearFlag == asfAccountTxnID) && sle->isFieldPresent (sfAccountTxnID)) { j_.trace << "Clear AccountTxnID"; sle->makeFieldAbsent (sfAccountTxnID); } // // EmailHash // if (ctx_.tx.isFieldPresent (sfEmailHash)) { uint128 const uHash = ctx_.tx.getFieldH128 (sfEmailHash); if (!uHash) { j_.trace << "unset email hash"; sle->makeFieldAbsent (sfEmailHash); } else { j_.trace << "set email hash"; sle->setFieldH128 (sfEmailHash, uHash); } } // // WalletLocator // if (ctx_.tx.isFieldPresent (sfWalletLocator)) { uint256 const uHash = ctx_.tx.getFieldH256 (sfWalletLocator); if (!uHash) { j_.trace << "unset wallet locator"; sle->makeFieldAbsent (sfWalletLocator); } else { j_.trace << "set wallet locator"; sle->setFieldH256 (sfWalletLocator, uHash); } } // // MessageKey // if (ctx_.tx.isFieldPresent (sfMessageKey)) { Blob const messageKey = ctx_.tx.getFieldVL (sfMessageKey); if (messageKey.empty ()) { j_.debug << "set message key"; sle->makeFieldAbsent (sfMessageKey); } else { j_.debug << "set message key"; sle->setFieldVL (sfMessageKey, messageKey); } } // // Domain // if (ctx_.tx.isFieldPresent (sfDomain)) { Blob const domain = ctx_.tx.getFieldVL (sfDomain); if (domain.empty ()) { j_.trace << "unset domain"; sle->makeFieldAbsent (sfDomain); } else { j_.trace << "set domain"; sle->setFieldVL (sfDomain, domain); } } // // TransferRate // if (ctx_.tx.isFieldPresent (sfTransferRate)) { std::uint32_t uRate = ctx_.tx.getFieldU32 (sfTransferRate); if (uRate == 0 || uRate == QUALITY_ONE) { j_.trace << "unset transfer rate"; sle->makeFieldAbsent (sfTransferRate); } else if (uRate > QUALITY_ONE) { j_.trace << "set transfer rate"; sle->setFieldU32 (sfTransferRate, uRate); } } if (uFlagsIn != uFlagsOut) sle->setFieldU32 (sfFlags, uFlagsOut); return tesSUCCESS; }
void run() { // Construct a seed. RippleAddress naSeed; expect (naSeed.setSeedGeneric ("masterpassphrase")); expect (naSeed.humanSeed () == "snoPBrXtMeMyMHUVTgbuqAfg1SUTb", naSeed.humanSeed ()); // Create node public/private key pair RippleAddress naNodePublic = RippleAddress::createNodePublic (naSeed); RippleAddress naNodePrivate = RippleAddress::createNodePrivate (naSeed); expect (naNodePublic.humanNodePublic () == "n94a1u4jAz288pZLtw6yFWVbi89YamiC6JBXPVUj5zmExe5fTVg9", naNodePublic.humanNodePublic ()); expect (naNodePrivate.humanNodePrivate () == "pnen77YEeUd4fFKG7iycBWcwKpTaeFRkW2WFostaATy1DSupwXe", naNodePrivate.humanNodePrivate ()); // Check node signing. Blob vucTextSrc = strCopy ("Hello, nurse!"); uint256 uHash = sha512Half(makeSlice(vucTextSrc)); Blob vucTextSig; naNodePrivate.signNodePrivate (uHash, vucTextSig); expect (naNodePublic.verifyNodePublic (uHash, vucTextSig, ECDSA::strict), "Verify failed."); // Construct a public generator from the seed. RippleAddress generator = RippleAddress::createGeneratorPublic (naSeed); expect (generator.humanGenerator () == "fhuJKrhSDzV2SkjLn9qbwm5AaRmrxDPfFsHDCP6yfDZWcxDFz4mt", generator.humanGenerator ()); // Create ed25519 account public/private key pair. KeyPair keys = generateKeysFromSeed (KeyType::ed25519, naSeed); expectEquals (keys.publicKey.humanAccountPublic(), "aKGheSBjmCsKJVuLNKRAKpZXT6wpk2FCuEZAXJupXgdAxX5THCqR"); // Check ed25519 account signing. vucTextSig = keys.secretKey.accountPrivateSign (vucTextSrc); expect (!vucTextSig.empty(), "ed25519 signing failed."); expect (keys.publicKey.accountPublicVerify (vucTextSrc, vucTextSig, ECDSA()), "ed25519 verify failed."); // Create account #0 public/private key pair. RippleAddress naAccountPublic0 = RippleAddress::createAccountPublic (generator, 0); RippleAddress naAccountPrivate0 = RippleAddress::createAccountPrivate (generator, naSeed, 0); expect (toBase58(calcAccountID(naAccountPublic0)) == "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh"); expect (naAccountPublic0.humanAccountPublic () == "aBQG8RQAzjs1eTKFEAQXr2gS4utcDiEC9wmi7pfUPTi27VCahwgw", naAccountPublic0.humanAccountPublic ()); // Create account #1 public/private key pair. RippleAddress naAccountPublic1 = RippleAddress::createAccountPublic (generator, 1); RippleAddress naAccountPrivate1 = RippleAddress::createAccountPrivate (generator, naSeed, 1); expect (toBase58(calcAccountID(naAccountPublic1)) == "r4bYF7SLUMD7QgSLLpgJx38WJSY12ViRjP"); expect (naAccountPublic1.humanAccountPublic () == "aBPXpTfuLy1Bhk3HnGTTAqnovpKWQ23NpFMNkAF6F1Atg5vDyPrw", naAccountPublic1.humanAccountPublic ()); // Check account signing. vucTextSig = naAccountPrivate0.accountPrivateSign (vucTextSrc); expect (!vucTextSig.empty(), "Signing failed."); expect (naAccountPublic0.accountPublicVerify (vucTextSrc, vucTextSig, ECDSA::strict), "Verify failed."); expect (!naAccountPublic1.accountPublicVerify (vucTextSrc, vucTextSig, ECDSA::not_strict), "Anti-verify failed."); expect (!naAccountPublic1.accountPublicVerify (vucTextSrc, vucTextSig, ECDSA::strict), "Anti-verify failed."); vucTextSig = naAccountPrivate1.accountPrivateSign (vucTextSrc); expect (!vucTextSig.empty(), "Signing failed."); expect (naAccountPublic1.accountPublicVerify (vucTextSrc, vucTextSig, ECDSA::strict), "Verify failed."); expect (!naAccountPublic0.accountPublicVerify (vucTextSrc, vucTextSig, ECDSA::not_strict), "Anti-verify failed."); expect (!naAccountPublic0.accountPublicVerify (vucTextSrc, vucTextSig, ECDSA::strict), "Anti-verify failed."); // Check account encryption. Blob vucTextCipher = naAccountPrivate0.accountPrivateEncrypt (naAccountPublic1, vucTextSrc); Blob vucTextRecovered = naAccountPrivate1.accountPrivateDecrypt (naAccountPublic0, vucTextCipher); expect (vucTextSrc == vucTextRecovered, "Encrypt-decrypt failed."); { RippleAddress nSeed; uint128 seed1, seed2; seed1.SetHex ("71ED064155FFADFA38782C5E0158CB26"); nSeed.setSeed (seed1); expect (nSeed.humanSeed() == "shHM53KPZ87Gwdqarm1bAmPeXg8Tn", "Incorrect human seed"); expect (nSeed.humanSeed1751() == "MAD BODY ACE MINT OKAY HUB WHAT DATA SACK FLAT DANA MATH", "Incorrect 1751 seed"); } }