diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1231,6 +1231,45 @@ // Disabled opcodes. return set_error(serror, SCRIPT_ERR_DISABLED_OPCODE); } + // (in size -- out) + if (stack.size() < 2) { + return set_error( + serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + } + CScriptNum num(stacktop(-2), fRequireMinimal); + int64_t size = CScriptNum(stacktop(-1), fRequireMinimal).getint(); + if (size < 1 || static_cast(size) > CScriptNum::nDefaultMaxNumSize) { + return set_error( + serror, SCRIPT_ERR_INVALID_NUM2BIN_OPERATION); + } + // Produces a byte vector of num and check if input size + // is valid + valtype vchNum = num.getvch(); + if (size < vchNum.size()) { + return set_error( + serror, SCRIPT_ERR_INVALID_NUM2BIN_OPERATION); + } + // Initialize byte vector for result + valtype result; + result.reserve(size); + bool neg{false}; + // Avoid negative zero + if (!vchNum.empty()) { + neg = *vchNum.rbegin() & 0x80; + *vchNum.rbegin() &= ~0x80; + } + // Pad result to declared input size + size_t pad = size - vchNum.size(); + for (uint8_t i = 0; i < pad; ++i) { + result.push_back(0); + } + for (auto i = vchNum.rbegin(); i != vchNum.rend(); ++i) { + result.push_back(*i); + } + if (neg) *result.begin() |= 0x80; + stack.pop_back(); + stack.pop_back(); + stack.push_back(result); } break; default: