Interesting proposal and a great contrast of options v.s. OP_TWEAKADD. I have a few notes which might strengthen this proposal:
I would suggest adding an operation OP_EC_LIFT_X_EVEN which "undos" OP_EC_POINT_X_COORD (not perfectly because of parity). This is helpful if OP_IKEY is used.
I would also suggest adding OP_EC_GENERATOR which pushes G onto the stack, rather than taking a 0 to mean G. This is more composable, as presently you have:
<x: [u8;32]> <y : Either<0, [u8;33]> OP_EC_POINT_MUL -> Either<0, [u8;33]>
therefore scripts like:
<blah> SHA256 <[0; 32]> <0> OP_EC_POINT_MUL OP_EC_POINT_MUL
will return: h(blah) G
rather than more straightforwardly carrying the point at infinity onwards.
If you instead had OP_G:
<blah> SHA256 <[0; 32]> OP_EC_GENERATOR OP_EC_POINT_MUL OP_EC_POINT_MUL
will return: point at infinity
then you'd get more correct multiplication chaining.
This lets you implement OP_TWEAKADD as:
<H> OP_EC_GENERATOR OP_EC_POINT_MUL OP_INTERNALKEY OP_EC_LIFT_X_EVEN OP_EC_POINT_ADD
v.s.
<H> OP_IKEY OP_TWEAKADD
Note: The BIP incorrectly gives:
<tweak> <empty_vector> OP_EC_POINT_MUL # tweak*G (33-byte)
<internal_key> OP_EC_POINT_ADD # P + tweak*G (33-byte)
OP_EC_POINT_X_COORD # Extract x-coordinate (32-byte)
the internal key, as specified, must be lifted first before adding.