Mixed Boolean-Arithmetic (MBA) obfuscation hides numbers and math by rewriting simple operations as equivalent-but-complex mixes of arithmetic (+ - *) and bitwise (^ & | ~) operators. For example x + y becomes (x ^ y) + 2*(x & y) — provably identical for every integer (tested below), but far harder to read or constant-fold. Obfuscators use it to bury constants (a license key, a threshold) and the math around them so a reverse-engineer can't grep or simplify them. It's a deterrent, not encryption. Our Python Obfuscator can apply MBA-style integer encoding as one of its layers.
Constants are one of the loudest tells in compiled or shipped code. A license check like if key == 0x1F3A9, a threshold if credits > 1000, a magic number — a reverse-engineer finds them with a text search or by letting the compiler constant-fold. Mixed Boolean-Arithmetic (MBA) obfuscation exists to erase those tells: it rewrites the math into a tangle of bitwise and arithmetic operators that computes the identical result but reveals nothing.
MBA is a well-studied technique (used by academic tools and commercial protectors alike), and the core of it is a set of provable identities. I verified each one below across 20,000 random inputs on Python 3.14 — including negatives — so you can trust they hold, not just look plausible.
What is Mixed Boolean Arithmetic?
Ordinary code mixes two worlds that are usually kept apart: arithmetic (+, -, *) and bitwise/boolean (^, &, |, ~) operators. MBA deliberately combines them into expressions that are *algebraically equivalent* to a simple operation but structurally alien. The classic example — addition rewritten with XOR and AND:
x + y == (x ^ y) + 2 * (x & y)# intuition: (x ^ y) is addition WITHOUT carries;# (x & y) is exactly the bits that carry, shifted left once (x2).# add them back and you've reconstructed x + y — for every integer.
Because it's a true identity, you can substitute it anywhere x + y appears and the program behaves *exactly* the same — but the + is gone, and so is any chance of a quick read.
The identities (tested on 20,000 inputs each)
Here are the workhorse MBA identities. Every one held across 20,000 random (x, y) pairs including negatives — real output, not hand-waving:
import randomdef holds(f, g, n=20000):return all(f(x, y) == g(x, y)for x, y in ((random.randint(-1000, 1000),random.randint(-1000, 1000)) for _ in range(n)))print(holds(lambda x, y: x + y, lambda x, y: (x ^ y) + 2*(x & y))) # Trueprint(holds(lambda x, y: x ^ y, lambda x, y: (x | y) - (x & y))) # Trueprint(holds(lambda x, y: x & y, lambda x, y: (x | y) - (x ^ y))) # True
| Simple op | MBA-equivalent | Verified |
|---|---|---|
x + y | (x ^ y) + 2*(x & y) | ✓ |
x + y | (x | y) + (x & y) | ✓ |
x - y | (x ^ y) - 2*(~x & y) | ✓ |
x ^ y | (x | y) - (x & y) | ✓ |
x & y | (x | y) - (x ^ y) | ✓ |
x | y | (x & y) + (x ^ y) | ✓ |
These are the base cases. Real MBA obfuscators nest them — rewriting the ^ and & inside an identity with *more* identities — so a single + explodes into a deep tree where no original operator remains.
How it hides a constant
The same trick erases literal constants. Instead of 1337 sitting in the code for a text search to find, express it as the result of an MBA operation over two split values — 1337 = 1000 + 337, then apply the addition identity:
# before: the constant is right thereLICENSE = 1337# after: 1337 never appears — it's computed by an MBA identityLICENSE = (1000 ^ 337) + 2 * (1000 & 337) # == 1337, testedassert LICENSE == 1337 # holds
Now a grep 1337 finds nothing, and the two operands (1000, 337) are arbitrary — an obfuscator can pick different splits every build, so the same constant looks different each time. Scale that across every literal and comparison in a licensing routine and the logic stops being readable at a glance.
Why MBA is hard to reverse
You might think a reverse-engineer just simplifies it back. In practice that's genuinely hard, for a specific reason: general MBA simplification is a known-difficult problem. Standard compiler constant-folding and peephole optimizers don't reduce mixed boolean-arithmetic expressions, because they don't have algebraic rules that cross the arithmetic/bitwise boundary. Recovering the original requires specialized MBA solvers (tools like SSPAM, Arybo, or SMT-assisted simplifiers), and even those struggle as expressions get deep and nonlinear.
MBA raises the *cost* of understanding the math — it is not encryption. A determined analyst with the right tools and time can still reduce it. As with all obfuscation, the goal is to make reversing cost more than rewriting from scratch, not to be unbreakable.
The trade-offs
- Size and speed: each substitution replaces one op with several, and nesting multiplies that — heavy MBA can noticeably grow the code and slow hot loops, so it's best applied to *sensitive* math (keys, checks), not every arithmetic line.
- Correctness is exact — if the identities are exact. The identities above are provably equal for Python's arbitrary-precision integers; a good obfuscator only uses proven identities so behavior never changes.
- It's one layer. MBA hides *numbers and math*; it does nothing for names, strings, or control flow. Real protection layers it with the other techniques below.
Apply MBA to your Python
Doing this by hand is tedious and error-prone — you have to keep every substitution provably equal. Our free Python Obfuscator applies MBA-style integer encoding as one of its layers, so the constants and arithmetic in your code come out as opaque expressions automatically, with the output still standalone, runnable Python.
MBA is strongest as part of a layered approach. Pair it with the other transforms, each covered in its own guide: control-flow flattening, identifier renaming, junk-code injection, and string encryption. The full picture is in Python obfuscation explained.
Obfuscate your Python — free
Apply MBA-style integer encoding plus renaming, string encryption and control-flow flattening in one pass. In your browser, standalone output.
Open the Python ObfuscatorFree tools mentioned here
Related guides
Frequently asked questions
What is Mixed Boolean Arithmetic (MBA)?
MBA is an obfuscation technique that rewrites arithmetic and boolean operations as equivalent but complex expressions mixing both kinds of operators — for example x + y becomes (x ^ y) + 2*(x & y). The result is provably identical for all integers but much harder to read, grep, or constant-fold, so it hides constants and math from reverse-engineers.
Is x + y really equal to (x ^ y) + 2*(x & y)?
Yes, for every integer. (x ^ y) is addition without carries, and (x & y) is exactly the bits that carry, which shifted left once (times 2) add the carries back. Tested across 20,000 random inputs including negatives on Python 3.14, it holds every time.
Does MBA obfuscation slow down my code?
It can. Each substitution turns one operation into several, and nesting multiplies that, so heavy MBA grows code size and can slow hot loops. Apply it to sensitive math — license checks, keys, thresholds — rather than every arithmetic expression, and benchmark if it runs in a tight loop.
Can MBA obfuscation be reversed?
In principle yes, but it's hard. Ordinary compiler optimizers and constant-folding don't simplify mixed boolean-arithmetic, so reversing it needs specialized MBA solvers (SSPAM, Arybo, SMT-based tools), and even those struggle with deep, nested, nonlinear expressions. MBA raises the cost of reversing; it is not unbreakable encryption.
How do I apply MBA to Python code?
Substitute proven MBA identities for the operations you want to hide, nest them for depth, and verify the rewrite matches the original across many inputs. Doing it by hand is error-prone, so most people use an obfuscator: our free Python Obfuscator applies MBA-style integer encoding automatically as one layer and returns standalone, runnable Python.