JS bit operations are funny
We almost certainly don't care, but the ASN.1 has some amount of silliness with numbers that don't fit in a signed int32. Also lengths. The quirks come from how JavaScript's "all numbers are doubles" interact with bit operations. The short version is that all bit operations call the internal ToInt32 before doing anything to the number. So a number that deals with bits is "natively" signed. There is one exception: >>> (as opposed to >>) calls ToUint32.
Anyway, this has various weird results, such as (0x80000000 >> 0) < 0 and (1 << 31) < 0. If you want to get the unsigned version of 1 << 31, you actually need to do (1 << 31) >>> 0. There is no <<<. (>> and >>> actually differ in the bits you get because of sign extension, but << and <<< wouldn't if the latter existed.)
I think I got the cases that matter right, but it would be worth double-checking.
This does suggest that, if we're dealing with bitmasks and the like internally, they probably should be signed. I forget what we did. I think most of it's in our crypto libraries, so we might not have much of it.