My question refers to EdDSA as specified in RFC 8032.

I get from the RFC that ed25519 and ed25519ph are two different instances of EdDSA mainly differing in the fact that that in the case of ed25519ph the hash of the message is signed.

Step 2 of the Sign process is:

$SHA\mbox{-}512(dom2(F, C) || prefix || PH(M))$

where in the case of ed25519 the $PH$ function is the identity function and in the case of ed25519ph its for example an implementation of SHA512. However, the part I am curious about it that this isn't the only difference between the two.

According to the RFC $dom2(F,C)$ actually is also different:

dom2(x, y): The blank octet string when signing or verifying Ed25519. Otherwise, the octet string: "SigEd25519 no Ed25519 collisions" || octet(x) || octet(OLEN(y)) || y, where x is in range 0-255 and y is an octet string of at most 255 octets. "SigEd25519 no Ed25519 collisions" is in ASCII (32 octets).

What's the reason for that? If this wasn't the case one could construct ed25519ph by simply hashing the message and passing it as input to an implementation of ed25519. The way its specified this construction wouldn't be compatible to an implementation of ed25519ph (because of the dom2 prefix).


1 Answer 1


This is just a preventive measure. Without this separation, an attacker knowing ed25519ph(m) would also learn ed25519(h(m)).

I'm not aware of any real-world protocol using both simultaneously and where that would be an issue, but it's not far-fetched to think that it could be the case.

Domain separation is good hygiene and has become very common in new designs.

The choice of dom2() being a blank string when using ed25519 was only made to remain compatible with existing implementations.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.