bool static IsDefinedHashtypeSignature(const valtype &vchSig) {
    if (vchSig.size() == 0) {
        return false;
    }
    unsigned char nHashType = vchSig[vchSig.size() - 1] & (~(SIGHASH_ANYONECANPAY));
    if (nHashType < SIGHASH_ALL || nHashType > SIGHASH_SINGLE)
        return false;

    return true;
}
Beispiel #2
0
void checkCanonicalPubKey(const valtype &vchPubKey) {
    if (vchPubKey.size() < 33)
        throw runtime_error("Non-canonical public key: too short");
    if (vchPubKey[0] == 0x04) {
        if (vchPubKey.size() != 65)
            throw runtime_error("Non-canonical public key: invalid length for uncompressed key");
    } else if (vchPubKey[0] == 0x02 || vchPubKey[0] == 0x03) {
        if (vchPubKey.size() != 33)
            throw runtime_error("Non-canonical public key: invalid length for compressed key");
    } else {
        throw runtime_error("Non-canonical public key: compressed nor uncompressed");
    }
}
bool CastToBool(const valtype& vch)
{
    for (unsigned int i = 0; i < vch.size(); i++)
    {
        if (vch[i] != 0)
        {
            // Can be negative zero
            if (i == vch.size()-1 && vch[i] == 0x80)
                return false;
            return true;
        }
    }
    return false;
}
Beispiel #4
0
CBigNum CastToBigNum(const valtype& vch)
{
    if (vch.size() > nMaxNumSize)
        throw runtime_error("CastToBigNum() : overflow");
    // Get rid of extra leading zeros
    return CBigNum(CBigNum(vch).getvch());
}
Beispiel #5
0
bool IsCanonicalPubKey(const valtype &vchPubKey, unsigned int flags) {
    if (!(flags & SCRIPT_VERIFY_STRICTENC))
        return true;

    if (vchPubKey.size() < 33)
        return error("Non-canonical public key: too short");
    if (vchPubKey[0] == 0x04) {
        if (vchPubKey.size() != 65)
            return error("Non-canonical public key: invalid length for uncompressed key");
    } else if (vchPubKey[0] == 0x02 || vchPubKey[0] == 0x03) {
        if (vchPubKey.size() != 33)
            return error("Non-canonical public key: invalid length for compressed key");
    } else {
        return error("Non-canonical public key: neither compressed nor uncompressed");
    }
    return true;
}
Beispiel #6
0
bool static IsLowDERSignature(const valtype &vchSig, ScriptError* serror) {
    if (!IsValidSignatureEncoding(vchSig)) {
        return set_error(serror, SCRIPT_ERR_SIG_DER);
    }
    std::vector<unsigned char> vchSigCopy(vchSig.begin(), vchSig.begin() + vchSig.size() - 1);
    if (!CPubKey::CheckLowS(vchSigCopy)) {
        return set_error(serror, SCRIPT_ERR_SIG_HIGH_S);
    }
    return true;
}
bool static IsCompressedOrUncompressedPubKey(const valtype &vchPubKey) {
    if (vchPubKey.size() < 33) {
        //  Non-canonical public key: too short
        return false;
    }
    if (vchPubKey[0] == 0x04) {
        if (vchPubKey.size() != 65) {
            //  Non-canonical public key: invalid length for uncompressed key
            return false;
        }
    } else if (vchPubKey[0] == 0x02 || vchPubKey[0] == 0x03) {
        if (vchPubKey.size() != 33) {
            //  Non-canonical public key: invalid length for compressed key
            return false;
        }
    } else {
          //  Non-canonical public key: neither compressed nor uncompressed
          return false;
    }
    return true;
}
Beispiel #8
0
void MakeSameSize(valtype& vch1, valtype& vch2)
{
    // Lengthen the shorter one
    if (vch1.size() < vch2.size())
        vch1.resize(vch2.size(), 0);
    if (vch2.size() < vch1.size())
        vch2.resize(vch1.size(), 0);
}
Beispiel #9
0
bool IsCanonicalSignature(const valtype &vchSig, unsigned int flags) {
    if (!(flags & SCRIPT_VERIFY_STRICTENC))
        return true;

    // See https://bitcointalk.org/index.php?topic=8392.msg127623#msg127623
    // A canonical signature exists of: <30> <total len> <02> <len R> <R> <02> <len S> <S> <hashtype>
    // Where R and S are not negative (their first byte has its highest bit not set), and not
    // excessively padded (do not start with a 0 byte, unless an otherwise negative number follows,
    // in which case a single 0 byte is necessary and even required).
    if (vchSig.size() < 9)
        return error("Non-canonical signature: too short");
    if (vchSig.size() > 73)
        return error("Non-canonical signature: too long");
    unsigned char nHashType = vchSig[vchSig.size() - 1] & (~(SIGHASH_ANYONECANPAY));
    if (nHashType < SIGHASH_ALL || nHashType > SIGHASH_SINGLE)
        return error("Non-canonical signature: unknown hashtype byte");
    if (vchSig[0] != 0x30)
        return error("Non-canonical signature: wrong type");
    if (vchSig[1] != vchSig.size()-3)
        return error("Non-canonical signature: wrong length marker");
    unsigned int nLenR = vchSig[3];
    if (5 + nLenR >= vchSig.size())
        return error("Non-canonical signature: S length misplaced");
    unsigned int nLenS = vchSig[5+nLenR];
    if ((unsigned long)(nLenR+nLenS+7) != vchSig.size())
        return error("Non-canonical signature: R+S length mismatch");

    const unsigned char *R = &vchSig[4];
    if (R[-2] != 0x02)
        return error("Non-canonical signature: R value type mismatch");
    if (nLenR == 0)
        return error("Non-canonical signature: R length is zero");
    if (R[0] & 0x80)
        return error("Non-canonical signature: R value negative");
    if (nLenR > 1 && (R[0] == 0x00) && !(R[1] & 0x80))
        return error("Non-canonical signature: R value excessively padded");

    const unsigned char *S = &vchSig[6+nLenR];
    if (S[-2] != 0x02)
        return error("Non-canonical signature: S value type mismatch");
    if (nLenS == 0)
        return error("Non-canonical signature: S length is zero");
    if (S[0] & 0x80)
        return error("Non-canonical signature: S value negative");
    if (nLenS > 1 && (S[0] == 0x00) && !(S[1] & 0x80))
        return error("Non-canonical signature: S value excessively padded");

    if (flags & SCRIPT_VERIFY_LOW_S) {
        // If the S value is above the order of the curve divided by two, its
        // complement modulo the order could have been used instead, which is
        // one byte shorter when encoded correctly.
        if (!CKey::CheckSignatureElement(S, nLenS, true))
            return error("Non-canonical signature: S value is unnecessarily high");
    }

    return true;
}
Beispiel #10
0
bool static CheckSignatureEncoding(const valtype &vchSig, unsigned int flags, ScriptError* serror) {
    // Empty signature. Not strictly DER encoded, but allowed to provide a
    // compact way to provide an invalid signature for use with CHECK(MULTI)SIG
    if (vchSig.size() == 0) {
        return true;
    }
    if ((flags & (SCRIPT_VERIFY_DERSIG | SCRIPT_VERIFY_LOW_S | SCRIPT_VERIFY_STRICTENC)) != 0 && !IsValidSignatureEncoding(vchSig)) {
        return set_error(serror, SCRIPT_ERR_SIG_DER);
    } else if ((flags & SCRIPT_VERIFY_LOW_S) != 0 && !IsLowDERSignature(vchSig, serror)) {
        // serror is set
        return false;
    } else if ((flags & SCRIPT_VERIFY_STRICTENC) != 0 && !IsDefinedHashtypeSignature(vchSig)) {
        return set_error(serror, SCRIPT_ERR_SIG_HASHTYPE);
    }
    return true;
}
Beispiel #11
0
bool static CheckMinimalPush(const valtype& data, opcodetype opcode) {
    if (data.size() == 0) {
        // Could have used OP_0.
        return opcode == OP_0;
    } else if (data.size() == 1 && data[0] >= 1 && data[0] <= 16) {
        // Could have used OP_1 .. OP_16.
        return opcode == OP_1 + (data[0] - 1);
    } else if (data.size() == 1 && data[0] == 0x81) {
        // Could have used OP_1NEGATE.
        return opcode == OP_1NEGATE;
    } else if (data.size() <= 75) {
        // Could have used a direct push (opcode indicating number of bytes pushed + those bytes).
        return opcode == data.size();
    } else if (data.size() <= 255) {
        // Could have used OP_PUSHDATA.
        return opcode == OP_PUSHDATA1;
    } else if (data.size() <= 65535) {
        // Could have used OP_PUSHDATA2.
        return opcode == OP_PUSHDATA2;
    }
    return true;
}
Beispiel #12
0
void checkCanonicalSignature(const valtype &vchSig) {
    // See https://bitcointalk.org/index.php?topic=8392.msg127623#msg127623
    // A canonical signature exists of: <30> <total len> <02> <len R> <R> <02> <len S> <S> <hashtype>
    // Where R and S are not negative (their first byte has its highest bit not set), and not
    // excessively padded (do not start with a 0 byte, unless an otherwise negative number follows,
    // in which case a single 0 byte is necessary and even required).
    if (vchSig.size() < 9)
        throw runtime_error("Non-canonical signature: too short");
    if (vchSig.size() > 73)
        throw runtime_error("Non-canonical signature: too long");
    unsigned char nHashType = vchSig[vchSig.size() - 1] & (~(SIGHASH_ANYONECANPAY));
    if (nHashType < SIGHASH_ALL || nHashType > SIGHASH_SINGLE)
        throw runtime_error("Non-canonical signature: unknown hashtype byte");
    if (vchSig[0] != 0x30)
        throw runtime_error("Non-canonical signature: wrong type");
    if (vchSig[1] != vchSig.size()-3)
        throw runtime_error("Non-canonical signature: wrong length marker");
    unsigned int nLenR = vchSig[3];
    if (5 + nLenR >= vchSig.size())
        throw runtime_error("Non-canonical signature: S length misplaced");
    unsigned int nLenS = vchSig[5+nLenR];
    if ((unsigned long)(nLenR+nLenS+7) != vchSig.size())
        throw runtime_error("Non-canonical signature: R+S length mismatch");
    
    const unsigned char *R = &vchSig[4];
    if (R[-2] != 0x02)
        throw runtime_error("Non-canonical signature: R value type mismatch");
    if (nLenR == 0)
        throw runtime_error("Non-canonical signature: R length is zero");
    if (R[0] & 0x80)
        throw runtime_error("Non-canonical signature: R value negative");
    if (nLenR > 1 && (R[0] == 0x00) && !(R[1] & 0x80))
        throw runtime_error("Non-canonical signature: R value excessively padded");
    
    const unsigned char *S = &vchSig[6+nLenR];
    if (S[-2] != 0x02)
        throw runtime_error("Non-canonical signature: S value type mismatch");
    if (nLenS == 0)
        throw runtime_error("Non-canonical signature: S length is zero");
    if (S[0] & 0x80)
        throw runtime_error("Non-canonical signature: S value negative");
    if (nLenS > 1 && (S[0] == 0x00) && !(S[1] & 0x80))
        throw runtime_error("Non-canonical signature: S value excessively padded");
}
/**
 * A canonical signature exists of: <30> <total len> <02> <len R> <R> <02> <len S> <S> <hashtype>
 * Where R and S are not negative (their first byte has its highest bit not set), and not
 * excessively padded (do not start with a 0 byte, unless an otherwise negative number follows,
 * in which case a single 0 byte is necessary and even required).
 * 
 * See https://bitcredittalk.org/index.php?topic=8392.msg127623#msg127623
 */
bool static IsDERSignature(const valtype &vchSig) {

    if (vchSig.size() < 9) {
        //  Non-canonical signature: too short
        return false;
    }
    if (vchSig.size() > 73) {
        // Non-canonical signature: too long
        return false;
    }
    if (vchSig[0] != 0x30) {
        //  Non-canonical signature: wrong type
        return false;
    }
    if (vchSig[1] != vchSig.size()-3) {
        //  Non-canonical signature: wrong length marker
        return false;
    }
    unsigned int nLenR = vchSig[3];
    if (5 + nLenR >= vchSig.size()) {
        //  Non-canonical signature: S length misplaced
        return false;
    }
    unsigned int nLenS = vchSig[5+nLenR];
    if ((unsigned long)(nLenR+nLenS+7) != vchSig.size()) {
        //  Non-canonical signature: R+S length mismatch
        return false;
    }

    const unsigned char *R = &vchSig[4];
    if (R[-2] != 0x02) {
        //  Non-canonical signature: R value type mismatch
        return false;
    }
    if (nLenR == 0) {
        //  Non-canonical signature: R length is zero
        return false;
    }
    if (R[0] & 0x80) {
        //  Non-canonical signature: R value negative
        return false;
    }
    if (nLenR > 1 && (R[0] == 0x00) && !(R[1] & 0x80)) {
        //  Non-canonical signature: R value excessively padded
        return false;
    }

    const unsigned char *S = &vchSig[6+nLenR];
    if (S[-2] != 0x02) {
        //  Non-canonical signature: S value type mismatch
        return false;
    }
    if (nLenS == 0) {
        //  Non-canonical signature: S length is zero
        return false;
    }
    if (S[0] & 0x80) {
        //  Non-canonical signature: S value negative
        return false;
    }
    if (nLenS > 1 && (S[0] == 0x00) && !(S[1] & 0x80)) {
        //  Non-canonical signature: S value excessively padded
        return false;
    }
    return true;
}