EdDSA Signing with context

openssl at symsysresearch.com openssl at symsysresearch.com
Sun Jun 25 07:01:51 UTC 2023

I am using OpenSSL (3.1) and working to add EdDSA support to libacvp.  I 
have discovered that the EdDSA implementation appears to ignore the 
"context-string" input variable to a signing operation.

The man page for ED448 with 3.1 
(https://www.openssl.org/docs/man3.1/man7/Ed448.html) implies that only 
PureEdDSA is supported.  It contains the statement "No additional 
parameters can be set during one-shot signing or verification. In 
particular, because PureEdDSA is used, a digest must NOT be specified 
when signing or verifying."  In the notes section, it goes on to say 
"The PureEdDSA algorithm ... ".  These statements imply only support for 
Pure EdDSA and *not* pre-hash EdDSA.

The "manmaster" page for ED448 
(https://www.openssl.org/docs/manmaster/man7/Ed448.html) says something 
very different.  It discusses the use of an instance name to specify the 
mode, and mentions using both curves with pre-hash (using the "ph" 
postfix) and ED25519ctx.  It also defines a "context-string" parameter 
for providing the "context" input defined in RFC8032.  Both of these 
parameters are set using an OSSL_PARAM array.

My code to perform signing is based on the code example in the 
'manmaster'-version of the page, using the params array to specify the 
context (and instance).

In RFC8032, context is disallowed for PureEdDSA with ED25519 (page 
9-10), but is optional with ED448 (page 15).  Here, I believe 'optional' 
means it may or may not be provided by the user, not that it may or may 
not be implemented by the library.  This is my reading of the RFC and 
looks to be backed up with the test vectors at the end of the RFC (page 
31).  It also appears to be backed up with the CAVP test vectors offered 
by ACVP.  The PureED25519 vectors have no context (and all pass), but 
for PureED448 some 10 out of ~1000 vectors include context.  These 10 
test cases consistently fail (all others pass).

Looking through the code, EVP_DigestSignInit_ex() leads to 
eddsa_digest_signverify_init() at eddsa_sig.c:87.  Here, the params 
argument is marked unused, and indeed the code does not reference it.  
So, the instance name and context inputs are ignored when provided.

Continuing the code trace, EVP_DigestSign() leads to ed448_digest_sign() 
at eddsa_sig.c:189.  In that function, at line 221, is a call to 
ossl_ed448_sign().  The context ptr and length arguments in that 
function call are (NULL, 0).  So even if the context was properly 
retained from the init, it would not be passed on to the sign operation.

This investigation leads to a number of questions, the relevance of each 
is dependent on the answers to others:
1) Does 3.1 support only PureEdDSA, or does it also support HashEdDSA?  
Which of the conflicting docs is correct?
2) Is the analysis above correct that even PureEdDSA with ED448 does not 
support the use of a context input?
3) If context is supported, how does one specify it?
4) If pre-hash is supported, how does one specify it?

In its current state, without the support of context with ED448, OSSL 
3.1 (and likely all previous versions) cannot pass CAVP testing for 
SigGen.  PureED448 without context passes, and all PureED25519 pass as 
they don't use context.  HashEdDSA for both curves also fails all tests, 
but that's not surprising if HashEdDSA isn't supported.

There are currently errors in the ACVP-Server code related to SigVer, 
and it's possible that once those errors are resolved, OSSL will not 
pass SigVer either for the same lack-of-context reason (jury is still 

Please note my earlier question (submitted 6/20; no replies yet) about 
KeyVer testing that does noes not seem available.  Good news is that 
KeyGen passes!

Randy Steck
Symbiotic Systems research, LLC

More information about the openssl-users mailing list