T-SQL Secure String Comparison
As discussed in the comments, this isn't cryptographically secure. The most obvious reason is that the optimizer may choose to do any number of things. The most likely to be concerning are a change in order of operations, or a change in join methodology. If math.RangeInt does any kind of table access (I assume this gives you a numbers table equivalent) then table access type could affect it as well.

Additionally, the bail-early for inequal length exposes information if this assumption isn't met (from comments):


  [I] wrote the code under an assumption that doesn't hold in general: that the strings being compared are hashes and thus the length is public knowledge


Ignoring comments regarding cryptographic security, I think the implementation is straightforward and makes sense. To try and address the cryptography I have a few ideas, but I am not an expert and do not endorse rolling your own security and cryptography algorithms/libraries (or using my suggestions, ever, in production).


(click here to see the image on imgur, otherwise click the image to read the original informative and entertaining comic).

Now that we have that out of the way, I think to even come close to accomplishing this, we would need to do the following:


Stop using a table valued function - we're going to need several hints to ensure that this performs consistently, which we can't add to a TVF and auditing all uses of this would be too difficult. In particular, OPTION( FORCE ORDER, RECOMPILE, MAXDOP 1, OPTIMIZE FOR @x = 0x00, @y = 0x00 ) will be necessary.
Instead of CROSS APPLY math.RangeInt, I think you'll need to join to a materialized numbers table (see below)
You're going to have to remove the length check, and pad the two values to an even 8000 (this is tedious but not hard, and I think should be doable in constant time)


I picked those hints because we want to ensure that it always joins in the order we specify, and doesn't get clever. We want to prohibit parallelism as well so it behaves consistently. Optimizing for those constant values prevents it from getting smart with parameter sniffing. We may not need to recompile; in my gut I think we want it, but I don't have a great reason for this. We may want to set a min/max grant percentage to be the same, so we get consistent behavior based on memory grant. It might also be valuable to use the USE PLAN hint, which lets you hardcode the plan to use. This might be the best way to get a consistent execution.

We're also going to have to add join and table access hints; assuming that dbo.Numbers exists with a clustered index on the first (and only) column, we might be able to do this:

FULL OUTER LOOP JOIN dbo.Numbers WITH ( INDEX(0), FORCESCAN )
  ON Numbers.Number = [@xLength].n


This should run in the same amount of time no matter the length of the string, and the query will always use the same join and table access pattern.

Overall, I think this is a lot of reasons why implementing something cryptographically secure in SQL is a bad idea; I would guess there are a lot of things I'm missing that still prevent this from being "safe".