Пример #1
0
    void convertNonCanonical(std::string const& hex, std::string const& canonHex)
    {
        Blob b (loadSignature(hex));

        // The signature ought to at least be valid before we begin.
        expect (isValid (hex), "invalid signature");

        size_t len = b.size ();

        expect (!makeCanonicalECDSASig (&b[0], len), 
            "non-canonical signature was already canonical");

        expect (b.size () >= len,
            "canonicalized signature length longer than non-canonical");

        b.resize (len);

        expect (isCanonicalECDSASig (&b[0], len, ECDSA::strict),
            "canonicalized signature is not strictly canonical");

        Blob canonicalForm (loadSignature (canonHex));

        expect (b.size () == canonicalForm.size (),
            "canonicalized signature doesn't have the expected length");

        expect (std::equal (b.begin (), b.end (), canonicalForm.begin ()),
            "canonicalized signature isn't what we expected");
    }
void ConsensusTransSetSF::gotNode (bool fromFilter, const SHAMapNode& id, uint256 const& nodeHash,
                                   Blob& nodeData, SHAMapTreeNode::TNType type)
{
    if (fromFilter)
        return;

    m_nodeCache.insert (nodeHash, nodeData);

    if ((type == SHAMapTreeNode::tnTRANSACTION_NM) && (nodeData.size () > 16))
    {
        // this is a transaction, and we didn't have it
        WriteLog (lsDEBUG, TransactionAcquire) << "Node on our acquiring TX set is TXN we may not have";

        try
        {
            Serializer s (nodeData.begin () + 4, nodeData.end ()); // skip prefix
            SerializerIterator sit (s);
            SerializedTransaction::pointer stx = boost::make_shared<SerializedTransaction> (boost::ref (sit));
            assert (stx->getTransactionID () == nodeHash);
            getApp().getJobQueue ().addJob (jtTRANSACTION, "TXS->TXN",
                                           BIND_TYPE (&NetworkOPs::submitTransaction, &getApp().getOPs (), P_1, stx));
        }
        catch (...)
        {
            WriteLog (lsWARNING, TransactionAcquire) << "Fetched invalid transaction in proposed set";
        }
    }
}
Пример #3
0
bool to_currency(Currency& currency, std::string const& code)
{
    if (code.empty () || !code.compare (systemCurrencyCode()))
    {
        currency = beast::zero;
        return true;
    }

    static const int CURRENCY_CODE_LENGTH = 3;
    if (code.size () == CURRENCY_CODE_LENGTH)
    {
        Blob codeBlob (CURRENCY_CODE_LENGTH);

        std::transform (code.begin (), code.end (), codeBlob.begin (),
                        [](auto c)
                        {
                            return ::toupper(static_cast<unsigned char>(c));
                        });

        Serializer  s;

        s.addZeros (96 / 8);
        s.addRaw (codeBlob);
        s.addZeros (16 / 8);
        s.addZeros (24 / 8);

        s.get160 (currency, 0);
        return true;
    }

    if (40 == code.size ())
        return currency.SetHex (code);

    return false;
}
Пример #4
0
bool Base58::raw_decode (char const* first, char const* last, void* dest,
    std::size_t size, bool checked, Alphabet const& alphabet)
{
    CAutoBN_CTX pctx;
    CBigNum bn58 = 58;
    CBigNum bn = 0;
    CBigNum bnChar;

    // Convert big endian string to bignum
    for (char const* p = first; p != last; ++p)
    {
        int i (alphabet.from_char (*p));
        if (i == -1)
            return false;
        bnChar.setuint ((unsigned int) i);

        int const success (BN_mul (&bn, &bn, &bn58, pctx));

        assert (success);
        (void) success;

        bn += bnChar;
    }

    // Get bignum as little endian data
    Blob vchTmp = bn.getvch ();

    // Trim off sign byte if present
    if (vchTmp.size () >= 2 && vchTmp.end ()[-1] == 0 && vchTmp.end ()[-2] >= 0x80)
        vchTmp.erase (vchTmp.end () - 1);

    char* const out (static_cast <char*> (dest));

    // Count leading zeros
    int nLeadingZeros = 0;
    for (char const* p = first; p!=last && *p==alphabet[0]; p++)
        nLeadingZeros++;

    // Verify that the size is correct
    if (vchTmp.size() + nLeadingZeros != size)
        return false;

    // Fill the leading zeros
    memset (out, 0, nLeadingZeros);

    // Copy little endian data to big endian
    std::reverse_copy (vchTmp.begin (), vchTmp.end (),
        out + nLeadingZeros);

    if (checked)
    {
        char hash4 [4];
        fourbyte_hash256 (hash4, out, size - 4);
        if (memcmp (hash4, out + size - 4, 4) != 0)
            return false;
    }

    return true;
}
Пример #5
0
std::string RippleAddress::human(Blob& blob, VersionEncoding type)
{
	Blob vch(1, type);
	
	vch.insert(vch.end(), blob.begin(), blob.end());

	return Base58::encodeWithCheck(vch);
}
Пример #6
0
bool Base58::decode (const char* psz, Blob& vchRet, Alphabet const& alphabet)
{
    CAutoBN_CTX pctx;
    vchRet.clear ();
    CBigNum bn58 = 58;
    CBigNum bn = 0;
    CBigNum bnChar;

    while (isspace (*psz))
        psz++;

    // Convert big endian string to bignum
    for (const char* p = psz; *p; p++)
    {
        // VFALCO TODO Make this use the inverse table!
        //             Or better yet ditch this and call raw_decode
        //
        const char* p1 = strchr (alphabet.chars(), *p);

        if (p1 == nullptr)
        {
            while (isspace (*p))
                p++;

            if (*p != '\0')
                return false;

            break;
        }

        bnChar.setuint (p1 - alphabet.chars());

        if (!BN_mul (&bn, &bn, &bn58, pctx))
            throw bignum_error ("DecodeBase58 : BN_mul failed");

        bn += bnChar;
    }

    // Get bignum as little endian data
    Blob vchTmp = bn.getvch ();

    // Trim off sign byte if present
    if (vchTmp.size () >= 2 && vchTmp.end ()[-1] == 0 && vchTmp.end ()[-2] >= 0x80)
        vchTmp.erase (vchTmp.end () - 1);

    // Restore leading zeros
    int nLeadingZeros = 0;

    for (const char* p = psz; *p == alphabet.chars()[0]; p++)
        nLeadingZeros++;

    vchRet.assign (nLeadingZeros + vchTmp.size (), 0);

    // Convert little endian data to big endian
    std::reverse_copy (vchTmp.begin (), vchTmp.end (), vchRet.end () - vchTmp.size ());
    return true;
}
Пример #7
0
Blob strCopy (std::string const& strSrc)
{
    Blob vucDst;

    vucDst.resize (strSrc.size ());

    std::copy (strSrc.begin (), strSrc.end (), vucDst.begin ());

    return vucDst;
}
Пример #8
0
Blob SqliteDatabase::getBinary (int colIndex)
{
    const unsigned char*        blob    = reinterpret_cast<const unsigned char*> (sqlite3_column_blob (mCurrentStmt, colIndex));
    size_t                      iSize   = sqlite3_column_bytes (mCurrentStmt, colIndex);
    Blob    vucResult;

    vucResult.resize (iSize);
    std::copy (blob, blob + iSize, vucResult.begin ());

    return vucResult;
}
Пример #9
0
std::string strCopy (Blob const& vucSrc)
{
    std::string strDst;

    strDst.resize (vucSrc.size ());

    std::copy (vucSrc.begin (), vucSrc.end (), strDst.begin ());

    return strDst;

}
Пример #10
0
STVector256::STVector256(SerialIter& sit, SField const& name)
    : STBase(name)
{
    Blob data = sit.getVL ();
    auto const count = data.size () / (256 / 8);
    mValue.reserve (count);
    Blob::iterator begin = data.begin ();
    unsigned int uStart  = 0;
    for (unsigned int i = 0; i != count; i++)
    {
        unsigned int uEnd = uStart + (256 / 8);
        // This next line could be optimized to construct a default
        // uint256 in the vector and then copy into it
        mValue.push_back (uint256 (Blob (begin + uStart, begin + uEnd)));
        uStart  = uEnd;
    }
}
Пример #11
0
String ConvertToBase58(const ConstBuf& cbuf) {
	HashValue hash = HasherEng::GetCurrent()->HashForAddress(cbuf);
	Blob v = cbuf + Blob(hash.data(), 4);
	vector<char> r;

	vector<byte> tmp(v.Size+1, 0);
	std::reverse_copy(v.begin(), v.end(), tmp.begin());
	for (BigInteger n(&tmp[0], tmp.size()); Sign(n);) {
		pair<BigInteger, BigInteger> pp = div(n, 58);
		n = pp.first;
		r.insert(r.begin(), s_pszBase58[explicit_cast<int>(pp.second)]);
	}

	for (int i=0; i<v.Size && !v.constData()[i]; ++i)
		r.insert(r.begin(), s_pszBase58[0]);
	return String(&r[0], r.size());
}
Пример #12
0
String ConvertToBase58ShaSquare(const ConstBuf& cbuf) {
	SHA256 sha;
	HashValue hash = HashValue(sha.ComputeHash(sha.ComputeHash(cbuf)));
	Blob v = cbuf + Blob(hash.data(), 4);
	vector<char> r;

	vector<byte> tmp(v.Size+1, 0);
	std::reverse_copy(v.begin(), v.end(), tmp.begin());
	for (BigInteger n(&tmp[0], tmp.size()); Sign(n);) {
		pair<BigInteger, BigInteger> pp = div(n, 58);
		n = pp.first;
		r.insert(r.begin(), s_pszBase58[explicit_cast<int>(pp.second)]);
	}

	for (int i=0; i<v.Size && !v.constData()[i]; ++i)
		r.insert(r.begin(), s_pszBase58[0]);
	return String(&r[0], r.size());
}
Пример #13
0
bool Base58::decodeWithCheck (const char* psz, Blob& vchRet, Alphabet const& alphabet)
{
    if (!decode (psz, vchRet, alphabet))
        return false;

    if (vchRet.size () < 4)
    {
        vchRet.clear ();
        return false;
    }

    uint256 hash = SHA256Hash (vchRet.begin (), vchRet.end () - 4);

    if (memcmp (&hash, &vchRet.end ()[-4], 4) != 0)
    {
        vchRet.clear ();
        return false;
    }

    vchRet.resize (vchRet.size () - 4);
    return true;
}
Пример #14
0
// Return a new object from a SerializerIterator.
STVector256* STVector256::construct (SerializerIterator& u, SField::ref name)
{
    Blob data = u.getVL ();
    Blob ::iterator begin = data.begin ();

    std::unique_ptr<STVector256> vec (new STVector256 (name));

    int count = data.size () / (256 / 8);
    vec->mValue.reserve (count);

    unsigned int    uStart  = 0;

    for (unsigned int i = 0; i != count; i++)
    {
        unsigned int    uEnd    = uStart + (256 / 8);

        // This next line could be optimized to construct a default uint256 in the vector and then copy into it
        vec->mValue.push_back (uint256 (Blob (begin + uStart, begin + uEnd)));
        uStart  = uEnd;
    }

    return vec.release ();
}
Пример #15
0
SHAMapTreeNode::SHAMapTreeNode (const SHAMapNode& id, Blob const& rawNode, uint32 seq,
                                SHANodeFormat format, uint256 const& hash, bool hashValid) :
    SHAMapNode (id), mSeq (seq), mType (tnERROR), mIsBranch (0), mFullBelow (false)
{
    if (format == snfWIRE)
    {
        Serializer s (rawNode);
        int type = s.removeLastByte ();
        int len = s.getLength ();

        if ((type < 0) || (type > 4))
        {
#ifdef BEAST_DEBUG
            Log::out() << "Invalid wire format node";
            Log::out() << strHex (rawNode);
            assert (false);
#endif
            throw std::runtime_error ("invalid node AW type");
        }

        if (type == 0)
        {
            // transaction
            mItem = boost::make_shared<SHAMapItem> (s.getPrefixHash (HashPrefix::transactionID), s.peekData ());
            mType = tnTRANSACTION_NM;
        }
        else if (type == 1)
        {
            // account state
            if (len < (256 / 8))
                throw std::runtime_error ("short AS node");

            uint256 u;
            s.get256 (u, len - (256 / 8));
            s.chop (256 / 8);

            if (u.isZero ()) throw std::runtime_error ("invalid AS node");

            mItem = boost::make_shared<SHAMapItem> (u, s.peekData ());
            mType = tnACCOUNT_STATE;
        }
        else if (type == 2)
        {
            // full inner
            if (len != 512)
                throw std::runtime_error ("invalid FI node");

            for (int i = 0; i < 16; ++i)
            {
                s.get256 (mHashes[i], i * 32);

                if (mHashes[i].isNonZero ())
                    mIsBranch |= (1 << i);
            }

            mType = tnINNER;
        }
        else if (type == 3)
        {
            // compressed inner
            for (int i = 0; i < (len / 33); ++i)
            {
                int pos;
                s.get8 (pos, 32 + (i * 33));

                if ((pos < 0) || (pos >= 16)) throw std::runtime_error ("invalid CI node");

                s.get256 (mHashes[pos], i * 33);

                if (mHashes[pos].isNonZero ())
                    mIsBranch |= (1 << pos);
            }

            mType = tnINNER;
        }
        else if (type == 4)
        {
            // transaction with metadata
            if (len < (256 / 8))
                throw std::runtime_error ("short TM node");

            uint256 u;
            s.get256 (u, len - (256 / 8));
            s.chop (256 / 8);

            if (u.isZero ())
                throw std::runtime_error ("invalid TM node");

            mItem = boost::make_shared<SHAMapItem> (u, s.peekData ());
            mType = tnTRANSACTION_MD;
        }
    }

    else if (format == snfPREFIX)
    {
        if (rawNode.size () < 4)
        {
            WriteLog (lsINFO, SHAMapNode) << "size < 4";
            throw std::runtime_error ("invalid P node");
        }

        uint32 prefix = rawNode[0];
        prefix <<= 8;
        prefix |= rawNode[1];
        prefix <<= 8;
        prefix |= rawNode[2];
        prefix <<= 8;
        prefix |= rawNode[3];
        Serializer s (rawNode.begin () + 4, rawNode.end ());

        if (prefix == HashPrefix::transactionID)
        {
            mItem = boost::make_shared<SHAMapItem> (Serializer::getSHA512Half (rawNode), s.peekData ());
            mType = tnTRANSACTION_NM;
        }
        else if (prefix == HashPrefix::leafNode)
        {
            if (s.getLength () < 32)
                throw std::runtime_error ("short PLN node");

            uint256 u;
            s.get256 (u, s.getLength () - 32);
            s.chop (32);

            if (u.isZero ())
            {
                WriteLog (lsINFO, SHAMapNode) << "invalid PLN node";
                throw std::runtime_error ("invalid PLN node");
            }

            mItem = boost::make_shared<SHAMapItem> (u, s.peekData ());
            mType = tnACCOUNT_STATE;
        }
        else if (prefix == HashPrefix::innerNode)
        {
            if (s.getLength () != 512)
                throw std::runtime_error ("invalid PIN node");

            for (int i = 0; i < 16; ++i)
            {
                s.get256 (mHashes[i], i * 32);

                if (mHashes[i].isNonZero ())
                    mIsBranch |= (1 << i);
            }

            mType = tnINNER;
        }
        else if (prefix == HashPrefix::txNode)
        {
            // transaction with metadata
            if (s.getLength () < 32)
                throw std::runtime_error ("short TXN node");

            uint256 txID;
            s.get256 (txID, s.getLength () - 32);
            s.chop (32);
            mItem = boost::make_shared<SHAMapItem> (txID, s.peekData ());
            mType = tnTRANSACTION_MD;
        }
        else
        {
            WriteLog (lsINFO, SHAMapNode) << "Unknown node prefix " << std::hex << prefix << std::dec;
            throw std::runtime_error ("invalid node prefix");
        }
    }

    else
    {
        assert (false);
        throw std::runtime_error ("Unknown format");
    }

    if (hashValid)
    {
        mHash = hash;
#if RIPPLE_VERIFY_NODEOBJECT_KEYS
        updateHash ();
        assert (mHash == hash);
#endif
    }
    else
        updateHash ();
}
Пример #16
0
 friend bool load(Blob const& blob, SpecificMessage& msg) {
     msg.contents.assign(blob.begin(), blob.end());
     return true;
 }