diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -336,10 +336,9 @@ } if (opcode == OP_CAT || opcode == OP_SUBSTR || opcode == OP_LEFT || - opcode == OP_RIGHT || opcode == OP_INVERT || opcode == OP_AND || - opcode == OP_OR || opcode == OP_XOR || opcode == OP_2MUL || - opcode == OP_2DIV || opcode == OP_MUL || opcode == OP_DIV || - opcode == OP_MOD || opcode == OP_LSHIFT || + opcode == OP_RIGHT || opcode == OP_INVERT || + opcode == OP_2MUL || opcode == OP_2DIV || opcode == OP_MUL || + opcode == OP_DIV || opcode == OP_MOD || opcode == OP_LSHIFT || opcode == OP_RSHIFT) { // Disabled opcodes. return set_error(serror, SCRIPT_ERR_DISABLED_OPCODE); @@ -781,6 +780,42 @@ // // Bitwise logic // + case OP_AND: + case OP_OR: + case OP_XOR: { + // (x1 x2 - out) + if (stack.size() < 2) { + return set_error( + serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + } + valtype &vch1 = stacktop(-2); + valtype &vch2 = stacktop(-1); + // throw error if inputs are not the same size + if (vch1.size() != vch2.size()) { + return set_error( + serror, SCRIPT_ERR_INVALID_BITWISE_OPERATION); + } + + switch (opcode) { + case OP_AND: + for (size_t i = 0; i < vch1.size(); i++) { + vch1[i] &= vch2[i]; + } + break; + case OP_OR: + for (size_t i = 0; i < vch1.size(); i++) { + vch1[i] |= vch2[i]; + } + break; + case OP_XOR: + for (size_t i = 0; i < vch1.size(); i++) { + vch1[i] ^= vch2[i]; + } + break; + } + stack.pop_back(); + } break; + case OP_EQUAL: case OP_EQUALVERIFY: // case OP_NOTEQUAL: // use OP_NUMNOTEQUAL diff --git a/src/script/script_error.h b/src/script/script_error.h --- a/src/script/script_error.h +++ b/src/script/script_error.h @@ -33,6 +33,7 @@ SCRIPT_ERR_INVALID_STACK_OPERATION, SCRIPT_ERR_INVALID_ALTSTACK_OPERATION, SCRIPT_ERR_UNBALANCED_CONDITIONAL, + SCRIPT_ERR_INVALID_BITWISE_OPERATION, /* CHECKLOCKTIMEVERIFY and CHECKSEQUENCEVERIFY */ SCRIPT_ERR_NEGATIVE_LOCKTIME, diff --git a/src/script/script_error.cpp b/src/script/script_error.cpp --- a/src/script/script_error.cpp +++ b/src/script/script_error.cpp @@ -46,6 +46,8 @@ return "OP_RETURN was encountered"; case SCRIPT_ERR_UNBALANCED_CONDITIONAL: return "Invalid OP_IF construction"; + case SCRIPT_ERR_INVALID_BITWISE_OPERATION: + return "Invalid bitwise operation (check length of inputs)"; case SCRIPT_ERR_NEGATIVE_LOCKTIME: return "Negative locktime"; case SCRIPT_ERR_UNSATISFIED_LOCKTIME: