I'm not sure whether this is along the lines you're looking for (and quite possibly you've already figured out all of this and more), but here's a crude formalization and then some implementation thoughts. Conceptually, this tries to separate what it means to entangle several values from how entangled values are represented.
Conceptually, entangled values can be thought of as aggregates where the different components retain their values, don't interfere with each other, and can be independently extracted. A convenient way to think of such aggregates is as n-tuples of values; for simplicity I assume n = 2 here. Also, I assume that we have operations to construct tuples from a collection of values, and to extract the component values from a tuple.
We now need to be able to carry out operations on tuples.
For this, for each operation op in the original program we now have 2 versions: op1, which operates on the first component of a 2-tuple, and op2, which operates on the second component:
<a1,b1> op1 <a2,b2> = if (b1 == b2) then <(a1 op a2), b1> else undefined
<a1,b1> op2 <a2,b2> = if (a1 == a2) then <a1, (b1 op b2)> else undefined
Finally (and this is where the obfuscation comes in), we need a way to encode tuples as values and decode values into tuples. If the set of values is S, then we need two functions enc and dec that must be inverses of each other:
enc: S x S --> S (encode pairs of values as a single entangled value)
dec: S --> S x S (decode an entangled value into its components)
enc(dec(x)) = x for all x
dec(enc(x)) = x for all x
enc takes a pair of 16-bit values and embeds them into a 32-bit value w such that x occupies the low 16 bits of w and y occupies the high 16 bits of w; dec takes a 32-bit value and decodes them into a pair where x is the low 16 bits and y is the high 16 bits.
enc takes a pair <x,y> of 16 bit values and embeds them into a 32-bit word w such that x occupies the even-numbered bit positions of w and y occupies the odd-numbered bit positions of w (i.e., their bits are interlaced); dec takes a 32-bit value w and decodes them into a pair <x,y> such that x consists of the even-numbered bits of w and y consists of the odd-numbered bits of w.
From an implementation perspective, we'd like to be able to perform operations directly on encoded representations of values. For this, corresponding to each of the operations op1 and op2 above, we need to define "encoded" versions op1* and op2* that must satisfy the following soundness criterion:
for all x1, x2, and y: x1 op1* x2 = y IFF enc( dec(x1) op1 dec(x2) ) = y
and similarly for op2*.
A lot of details are omitted (mostly easy enough to work out), and this basic approach could be prettified in various ways, but I don't know whether this is along the lines you were asking for and also whether maybe this is pretty straightforward and you've already worked it all out for yourself. Anyway, I hope this is useful.
From @perror's comment (below) it seems clear that the formalization above is not powerful enough to capture the obfuscation he has in mind (though it might be possible to get a little mileage from generalizing the encoding/decoding functions enc and dec).
I had forgotten about this paper, which discusses a transformation that seems relevant (see Sec. 6.1, "Split variables"):
Christian Collberg, Clark Thomborson, and Douglas Low. Breaking Abstractions and Unstructuring Data Structures. IEEE International Conference on Computer Languages (ICCL'98), May 1998. (link)