See nodejs/node#60267
But Node.js having the same issue is not a reason for a standalone cryptography-oriented lib to do the same
As the collision happens in the string-to-bytes conversion, it affects everything on top of that: hashes, signatures, etc.
These strings survive JSON.stringify/parse and being sent over network
This can also result in hash(a0) === hash(b0), hash(a1) === hash(b1), hash(a0 + a1) !== hash(b0 + b1) and both of a0 + a1 and b0 + b1 being different well-formed strings.
Additionally, those strings with "equal hashes" can result in different numeric values when converted with new BN(a) v4 due to it also lacking proper input validation
> const [a, b] = [0, 1].map(i => String.fromCodePoint(0x10000)[i])
undefined
> a === b
false
> require('@noble/hashes/sha2.js').sha256(require('@noble/hashes/utils.js').utf8ToBytes(a)).toHex()
'83d544ccc223c057d2bf80d3f2a32982c32c3c0db8e2674820da5064783fb097'
> require('@noble/hashes/sha2.js').sha256(require('@noble/hashes/utils.js').utf8ToBytes(b)).toHex()
'83d544ccc223c057d2bf80d3f2a32982c32c3c0db8e2674820da5064783fb097'
> require('@noble/hashes/sha2.js').sha256(require('@noble/hashes/utils.js').utf8ToBytes('abc \udfff def')).toHex()
'52aabbf44f06a5f70051771d69b18b795ae587a9191721438c8360f6db935468'
> require('@noble/hashes/sha2.js').sha256(require('@noble/hashes/utils.js').utf8ToBytes('abc \ud800 def')).toHex()
'52aabbf44f06a5f70051771d69b18b795ae587a9191721438c8360f6db935468'
On all engines where available, use String.prototype.isWellFormed to guard.
On Hermes, see e.g. what I did in https://github.com/ExodusOSS/bytes/blob/main/utf8.js
See nodejs/node#60267
But Node.js having the same issue is not a reason for a standalone cryptography-oriented lib to do the same
As the collision happens in the string-to-bytes conversion, it affects everything on top of that: hashes, signatures, etc.
These strings survive JSON.stringify/parse and being sent over network
This can also result in
hash(a0) === hash(b0),hash(a1) === hash(b1),hash(a0 + a1) !== hash(b0 + b1)and both ofa0 + a1andb0 + b1being different well-formed strings.Additionally, those strings with "equal hashes" can result in different numeric values when converted with
new BN(a)v4 due to it also lacking proper input validationOn all engines where available, use
String.prototype.isWellFormedto guard.On Hermes, see e.g. what I did in https://github.com/ExodusOSS/bytes/blob/main/utf8.js