We have OP_HASH256 just for that.
That was a mistake, I didn't mean to hash the top stack element twice. It should have been something like this with a new OP code:
OP_HASH256 OP_SWAP OP_SHA256 OP_ROT OP_SHA256 OP_COMBINE3
[blk1][blk2][blk3]
OP_HASH256 -> [blk1][blk2][h3]
OP_SWAP -> [blk1][h3][blk2]
OP_SHA256 -> [blk1][h3][h2]
OP_ROT -> [h3][h2][blk1]
OP_SHA256 -> [h3][h2][h1]
OP_COMBINE3 -> [int]
This is not generic enough, it could be better defined as "3 OP_GETBLOCKS", where for example 3 is standard and anything else is non-standard.
That's a better idea and the number (eg. 3) could be part of the locking script instead to make it "already agreed upon".
OP_GETBLOCKS could also be defined in a way that we don't need what I explained above. It just takes n blocks computes hash of the block-header-hash and combines them (eg. SHA256(headerHash1) XOR SHA256(headerHash2))
To build a sidechain, you need support from miners, because they protect sending coins to and from the sidechain. If you don't have their support, then building in on top of LN is easier.
That's the beauty of a side-chain, you would be creating an altcoin that has its own network, blockchain and consensus rules. It can even have its own miners mining standalone new blocks with a different algorithm.
On the other hand wanting to do it on LN you will face the same problem needing new OP codes that don't exist in LN.