Merge pull request #2221 from SparkiDev/rfc8032

Support Ed25519ctx and Ed25519ph sign/verify algorithms
This commit is contained in:
toddouska
2019-05-01 15:45:03 -07:00
committed by GitHub
3 changed files with 510 additions and 26 deletions

View File

@ -45,6 +45,12 @@
#include <wolfssl/wolfcrypt/port/nxp/ksdk_port.h>
#endif
#if defined(HAVE_ED25519_SIGN) || defined(HAVE_ED25519_VERIFY)
#define ED25519CTX_SIZE 32
static const byte ed25519Ctx[ED25519CTX_SIZE] =
"SigEd25519 no Ed25519 collisions";
#endif
int wc_ed25519_make_public(ed25519_key* key, unsigned char* pubKey,
word32 pubKeySz)
@ -118,15 +124,19 @@ int wc_ed25519_make_key(WC_RNG* rng, int keySz, ed25519_key* key)
#ifdef HAVE_ED25519_SIGN
/*
in contains the message to sign
inlen is the length of the message to sign
inLen is the length of the message to sign
out is the buffer to write the signature
outLen [in/out] input size of out buf
output gets set as the final length of out
key is the ed25519 key to use when signing
type one of Ed25519, Ed25519ctx or Ed25519ph
context extra signing data
contextLen length of extra signing data
return 0 on success
*/
int wc_ed25519_sign_msg(const byte* in, word32 inlen, byte* out,
word32 *outLen, ed25519_key* key)
static int ed25519_sign_msg(const byte* in, word32 inLen, byte* out,
word32 *outLen, ed25519_key* key, byte type,
const byte* context, byte contextLen)
{
#ifdef FREESCALE_LTC_ECC
byte tempBuf[ED25519_PRV_KEY_SIZE];
@ -140,8 +150,10 @@ int wc_ed25519_sign_msg(const byte* in, word32 inlen, byte* out,
int ret;
/* sanity check on arguments */
if (in == NULL || out == NULL || outLen == NULL || key == NULL)
if (in == NULL || out == NULL || outLen == NULL || key == NULL ||
(context == NULL && contextLen != 0)) {
return BAD_FUNC_ARG;
}
if (!key->pubKeySet)
return BAD_FUNC_ARG;
@ -166,9 +178,19 @@ int wc_ed25519_sign_msg(const byte* in, word32 inlen, byte* out,
ret = wc_InitSha512(&sha);
if (ret != 0)
return ret;
if (type == Ed25519ctx || type == Ed25519ph) {
ret = wc_Sha512Update(&sha, ed25519Ctx, ED25519CTX_SIZE);
if (ret == 0)
ret = wc_Sha512Update(&sha, &type, sizeof(type));
if (ret == 0)
ret = wc_Sha512Update(&sha, &contextLen, sizeof(contextLen));
if (ret == 0 && context != NULL)
ret = wc_Sha512Update(&sha, context, contextLen);
}
if (ret == 0)
ret = wc_Sha512Update(&sha, az + ED25519_KEY_SIZE, ED25519_KEY_SIZE);
if (ret == 0)
ret = wc_Sha512Update(&sha, in, inlen);
ret = wc_Sha512Update(&sha, in, inLen);
if (ret == 0)
ret = wc_Sha512Final(&sha, nonce);
wc_Sha512Free(&sha);
@ -180,7 +202,8 @@ int wc_ed25519_sign_msg(const byte* in, word32 inlen, byte* out,
ltcPoint.X = &tempBuf[0];
ltcPoint.Y = &tempBuf[32];
LTC_PKHA_sc_reduce(nonce);
LTC_PKHA_Ed25519_PointMul(LTC_PKHA_Ed25519_BasePoint(), nonce, ED25519_KEY_SIZE, &ltcPoint, kLTC_Ed25519 /* result on Ed25519 */);
LTC_PKHA_Ed25519_PointMul(LTC_PKHA_Ed25519_BasePoint(), nonce,
ED25519_KEY_SIZE, &ltcPoint, kLTC_Ed25519 /* result on Ed25519 */);
LTC_PKHA_Ed25519_Compress(&ltcPoint, out);
#else
sc_reduce(nonce);
@ -196,11 +219,21 @@ int wc_ed25519_sign_msg(const byte* in, word32 inlen, byte* out,
ret = wc_InitSha512(&sha);
if (ret != 0)
return ret;
if (type == Ed25519ctx || type == Ed25519ph) {
ret = wc_Sha512Update(&sha, ed25519Ctx, ED25519CTX_SIZE);
if (ret == 0)
ret = wc_Sha512Update(&sha, &type, sizeof(type));
if (ret == 0)
ret = wc_Sha512Update(&sha, &contextLen, sizeof(contextLen));
if (ret == 0 && context != NULL)
ret = wc_Sha512Update(&sha, context, contextLen);
}
if (ret == 0)
ret = wc_Sha512Update(&sha, out, ED25519_SIG_SIZE/2);
if (ret == 0)
ret = wc_Sha512Update(&sha, key->p, ED25519_PUB_KEY_SIZE);
if (ret == 0)
ret = wc_Sha512Update(&sha, in, inlen);
ret = wc_Sha512Update(&sha, in, inLen);
if (ret == 0)
ret = wc_Sha512Final(&sha, hram);
wc_Sha512Free(&sha);
@ -218,20 +251,100 @@ int wc_ed25519_sign_msg(const byte* in, word32 inlen, byte* out,
return ret;
}
/*
in contains the message to sign
inLen is the length of the message to sign
out is the buffer to write the signature
outLen [in/out] input size of out buf
output gets set as the final length of out
key is the ed25519 key to use when signing
return 0 on success
*/
int wc_ed25519_sign_msg(const byte* in, word32 inLen, byte* out,
word32 *outLen, ed25519_key* key)
{
return ed25519_sign_msg(in, inLen, out, outLen, key, Ed25519, NULL, 0);
}
/*
in contains the message to sign
inLen is the length of the message to sign
out is the buffer to write the signature
outLen [in/out] input size of out buf
output gets set as the final length of out
key is the ed25519 key to use when signing
context extra signing data
contextLen length of extra signing data
return 0 on success
*/
int wc_ed25519ctx_sign_msg(const byte* in, word32 inLen, byte* out,
word32 *outLen, ed25519_key* key,
const byte* context, byte contextLen)
{
return ed25519_sign_msg(in, inLen, out, outLen, key, Ed25519ctx, context,
contextLen);
}
/*
hash contains the SHA-512 hash of the message to sign
hashLen is the length of the SHA-512 hash of the message to sign
out is the buffer to write the signature
outLen [in/out] input size of out buf
output gets set as the final length of out
key is the ed25519 key to use when signing
context extra signing data
contextLen length of extra signing data
return 0 on success
*/
int wc_ed25519ph_sign_hash(const byte* hash, word32 hashLen, byte* out,
word32 *outLen, ed25519_key* key,
const byte* context, byte contextLen)
{
return ed25519_sign_msg(hash, hashLen, out, outLen, key, Ed25519ph, context,
contextLen);
}
/*
in contains the message to sign
inLen is the length of the message to sign
out is the buffer to write the signature
outLen [in/out] input size of out buf
output gets set as the final length of out
key is the ed25519 key to use when signing
context extra signing data
contextLen length of extra signing data
return 0 on success
*/
int wc_ed25519ph_sign_msg(const byte* in, word32 inLen, byte* out,
word32 *outLen, ed25519_key* key,
const byte* context, byte contextLen)
{
int ret;
byte hash[WC_SHA512_DIGEST_SIZE];
ret = wc_Sha512Hash(in, inLen, hash);
if (ret != 0)
return ret;
return wc_ed25519ph_sign_hash(hash, sizeof(hash), out, outLen, key, context,
contextLen);
}
#endif /* HAVE_ED25519_SIGN */
#ifdef HAVE_ED25519_VERIFY
/*
sig is array of bytes containing the signature
siglen is the length of sig byte array
sigLen is the length of sig byte array
msg the array of bytes containing the message
msglen length of msg array
msgLen length of msg array
res will be 1 on successful verify and 0 on unsuccessful
key Ed25519 public key
return 0 and res of 1 on success
*/
int wc_ed25519_verify_msg(const byte* sig, word32 siglen, const byte* msg,
word32 msglen, int* res, ed25519_key* key)
static int ed25519_verify_msg(const byte* sig, word32 sigLen, const byte* msg,
word32 msgLen, int* res, ed25519_key* key,
byte type, const byte* context, byte contextLen)
{
byte rcheck[ED25519_KEY_SIZE];
byte h[WC_SHA512_DIGEST_SIZE];
@ -243,14 +356,16 @@ int wc_ed25519_verify_msg(const byte* sig, word32 siglen, const byte* msg,
wc_Sha512 sha;
/* sanity check on arguments */
if (sig == NULL || msg == NULL || res == NULL || key == NULL)
if (sig == NULL || msg == NULL || res == NULL || key == NULL ||
(context == NULL && contextLen != 0)) {
return BAD_FUNC_ARG;
}
/* set verification failed by default */
*res = 0;
/* check on basics needed to verify signature */
if (siglen < ED25519_SIG_SIZE || (sig[ED25519_SIG_SIZE-1] & 224))
if (sigLen < ED25519_SIG_SIZE || (sig[ED25519_SIG_SIZE-1] & 224))
return BAD_FUNC_ARG;
/* uncompress A (public key), test if valid, and negate it */
@ -263,11 +378,21 @@ int wc_ed25519_verify_msg(const byte* sig, word32 siglen, const byte* msg,
ret = wc_InitSha512(&sha);
if (ret != 0)
return ret;
if (type == Ed25519ctx || type == Ed25519ph) {
ret = wc_Sha512Update(&sha, ed25519Ctx, ED25519CTX_SIZE);
if (ret == 0)
ret = wc_Sha512Update(&sha, &type, sizeof(type));
if (ret == 0)
ret = wc_Sha512Update(&sha, &contextLen, sizeof(contextLen));
if (ret == 0 && context != NULL)
ret = wc_Sha512Update(&sha, context, contextLen);
}
if (ret == 0)
ret = wc_Sha512Update(&sha, sig, ED25519_SIG_SIZE/2);
if (ret == 0)
ret = wc_Sha512Update(&sha, key->p, ED25519_PUB_KEY_SIZE);
if (ret == 0)
ret = wc_Sha512Update(&sha, msg, msglen);
ret = wc_Sha512Update(&sha, msg, msgLen);
if (ret == 0)
ret = wc_Sha512Final(&sha, h);
wc_Sha512Free(&sha);
@ -302,6 +427,85 @@ int wc_ed25519_verify_msg(const byte* sig, word32 siglen, const byte* msg,
return ret;
}
/*
sig is array of bytes containing the signature
sigLen is the length of sig byte array
msg the array of bytes containing the message
msgLen length of msg array
res will be 1 on successful verify and 0 on unsuccessful
key Ed25519 public key
return 0 and res of 1 on success
*/
int wc_ed25519_verify_msg(const byte* sig, word32 sigLen, const byte* msg,
word32 msgLen, int* res, ed25519_key* key)
{
return ed25519_verify_msg(sig, sigLen, msg, msgLen, res, key, Ed25519, NULL,
0);
}
/*
sig is array of bytes containing the signature
sigLen is the length of sig byte array
msg the array of bytes containing the message
msgLen length of msg array
res will be 1 on successful verify and 0 on unsuccessful
key Ed25519 public key
context extra sigining data
contextLen length of extra sigining data
return 0 and res of 1 on success
*/
int wc_ed25519ctx_verify_msg(const byte* sig, word32 sigLen, const byte* msg,
word32 msgLen, int* res, ed25519_key* key,
const byte* context, byte contextLen)
{
return ed25519_verify_msg(sig, sigLen, msg, msgLen, res, key, Ed25519ctx,
context, contextLen);
}
/*
sig is array of bytes containing the signature
sigLen is the length of sig byte array
hash the array of bytes containing the SHA-512 hash of the message
hashLen length of hash array
res will be 1 on successful verify and 0 on unsuccessful
key Ed25519 public key
context extra sigining data
contextLen length of extra sigining data
return 0 and res of 1 on success
*/
int wc_ed25519ph_verify_hash(const byte* sig, word32 sigLen, const byte* hash,
word32 hashLen, int* res, ed25519_key* key,
const byte* context, byte contextLen)
{
return ed25519_verify_msg(sig, sigLen, hash, hashLen, res, key, Ed25519ph,
context, contextLen);
}
/*
sig is array of bytes containing the signature
sigLen is the length of sig byte array
msg the array of bytes containing the message
msgLen length of msg array
res will be 1 on successful verify and 0 on unsuccessful
key Ed25519 public key
context extra sigining data
contextLen length of extra sigining data
return 0 and res of 1 on success
*/
int wc_ed25519ph_verify_msg(const byte* sig, word32 sigLen, const byte* msg,
word32 msgLen, int* res, ed25519_key* key,
const byte* context, byte contextLen)
{
int ret;
byte hash[WC_SHA512_DIGEST_SIZE];
ret = wc_Sha512Hash(msg, msgLen, hash);
if (ret != 0)
return ret;
return wc_ed25519ph_verify_hash(sig, sigLen, hash, sizeof(hash), res, key,
context, contextLen);
}
#endif /* HAVE_ED25519_VERIFY */

View File

@ -18458,6 +18458,248 @@ done:
}
#endif /* WOLFSSL_TEST_CERT */
#if defined(HAVE_ED25519_SIGN) && defined(HAVE_ED25519_KEY_EXPORT) && \
defined(HAVE_ED25519_KEY_IMPORT)
static int ed25519ctx_test(void)
{
byte out[ED25519_SIG_SIZE];
word32 outlen;
#ifdef HAVE_ED25519_VERIFY
int verify;
#endif /* HAVE_ED25519_VERIFY */
ed25519_key key;
static const byte sKeyCtx[] = {
0x03,0x05,0x33,0x4e,0x38,0x1a,0xf7,0x8f,
0x14,0x1c,0xb6,0x66,0xf6,0x19,0x9f,0x57,
0xbc,0x34,0x95,0x33,0x5a,0x25,0x6a,0x95,
0xbd,0x2a,0x55,0xbf,0x54,0x66,0x63,0xf6
};
static const byte pKeyCtx[] = {
0xdf,0xc9,0x42,0x5e,0x4f,0x96,0x8f,0x7f,
0x0c,0x29,0xf0,0x25,0x9c,0xf5,0xf9,0xae,
0xd6,0x85,0x1c,0x2b,0xb4,0xad,0x8b,0xfb,
0x86,0x0c,0xfe,0xe0,0xab,0x24,0x82,0x92
};
static const byte sigCtx1[] = {
0x55,0xa4,0xcc,0x2f,0x70,0xa5,0x4e,0x04,
0x28,0x8c,0x5f,0x4c,0xd1,0xe4,0x5a,0x7b,
0xb5,0x20,0xb3,0x62,0x92,0x91,0x18,0x76,
0xca,0xda,0x73,0x23,0x19,0x8d,0xd8,0x7a,
0x8b,0x36,0x95,0x0b,0x95,0x13,0x00,0x22,
0x90,0x7a,0x7f,0xb7,0xc4,0xe9,0xb2,0xd5,
0xf6,0xcc,0xa6,0x85,0xa5,0x87,0xb4,0xb2,
0x1f,0x4b,0x88,0x8e,0x4e,0x7e,0xdb,0x0d
};
static const byte sigCtx2[] = {
0xcc,0x5e,0x63,0xa2,0x7e,0x94,0xaf,0xd3,
0x41,0x83,0x38,0xd2,0x48,0x6f,0xa9,0x2a,
0xf9,0x91,0x7c,0x2d,0x98,0x9e,0x06,0xe5,
0x02,0x77,0x72,0x1c,0x34,0x38,0x18,0xb4,
0x21,0x96,0xbc,0x29,0x2e,0x68,0xf3,0x4d,
0x85,0x9b,0xbe,0xad,0x17,0x9f,0x54,0x54,
0x2d,0x4b,0x04,0xdc,0xfb,0xfa,0x4a,0x68,
0x4e,0x39,0x50,0xfb,0x1c,0xcd,0x8d,0x0d
};
static const byte msgCtx[] = {
0xf7,0x26,0x93,0x6d,0x19,0xc8,0x00,0x49,
0x4e,0x3f,0xda,0xff,0x20,0xb2,0x76,0xa8
};
static const byte contextCtx[] = {
0x66,0x6f,0x6f
};
outlen = sizeof(out);
XMEMSET(out, 0, sizeof(out));
if (wc_ed25519_import_private_key(sKeyCtx, ED25519_KEY_SIZE, pKeyCtx,
sizeof(pKeyCtx), &key) != 0)
return -9020;
if (wc_ed25519ctx_sign_msg(msgCtx, sizeof(msgCtx), out, &outlen, &key,
contextCtx, sizeof(contextCtx)) != 0)
return -9021;
if (XMEMCMP(out, sigCtx1, 64))
return -9022;
#if defined(HAVE_ED25519_VERIFY)
/* test verify on good msg */
if (wc_ed25519ctx_verify_msg(out, outlen, msgCtx, sizeof(msgCtx), &verify,
&key, contextCtx, sizeof(contextCtx)) != 0 ||
verify != 1)
return -9023;
#endif
if (wc_ed25519ctx_sign_msg(msgCtx, sizeof(msgCtx), out, &outlen, &key, NULL,
0) != 0)
return -9025;
if (XMEMCMP(out, sigCtx2, 64))
return -9026;
#if defined(HAVE_ED25519_VERIFY)
/* test verify on good msg */
if (wc_ed25519ctx_verify_msg(out, outlen, msgCtx, sizeof(msgCtx), &verify,
&key, NULL, 0) != 0 || verify != 1)
return -9027;
#endif
wc_ed25519_free(&key);
return 0;
}
static int ed25519ph_test(void)
{
byte out[ED25519_SIG_SIZE];
word32 outlen;
#ifdef HAVE_ED25519_VERIFY
int verify;
#endif /* HAVE_ED25519_VERIFY */
ed25519_key key;
static const byte sKeyPh[] = {
0x83,0x3f,0xe6,0x24,0x09,0x23,0x7b,0x9d,
0x62,0xec,0x77,0x58,0x75,0x20,0x91,0x1e,
0x9a,0x75,0x9c,0xec,0x1d,0x19,0x75,0x5b,
0x7d,0xa9,0x01,0xb9,0x6d,0xca,0x3d,0x42
};
static const byte pKeyPh[] = {
0xec,0x17,0x2b,0x93,0xad,0x5e,0x56,0x3b,
0xf4,0x93,0x2c,0x70,0xe1,0x24,0x50,0x34,
0xc3,0x54,0x67,0xef,0x2e,0xfd,0x4d,0x64,
0xeb,0xf8,0x19,0x68,0x34,0x67,0xe2,0xbf
};
static const byte sigPh1[] = {
0x98,0xa7,0x02,0x22,0xf0,0xb8,0x12,0x1a,
0xa9,0xd3,0x0f,0x81,0x3d,0x68,0x3f,0x80,
0x9e,0x46,0x2b,0x46,0x9c,0x7f,0xf8,0x76,
0x39,0x49,0x9b,0xb9,0x4e,0x6d,0xae,0x41,
0x31,0xf8,0x50,0x42,0x46,0x3c,0x2a,0x35,
0x5a,0x20,0x03,0xd0,0x62,0xad,0xf5,0xaa,
0xa1,0x0b,0x8c,0x61,0xe6,0x36,0x06,0x2a,
0xaa,0xd1,0x1c,0x2a,0x26,0x08,0x34,0x06
};
static const byte sigPh2[] = {
0xe0,0x39,0x70,0x2b,0x4c,0x25,0x95,0xa6,
0xa5,0x41,0xac,0x85,0x09,0x23,0x6e,0x29,
0x90,0x47,0x47,0x95,0x33,0x0c,0x9b,0x34,
0xa7,0x5f,0x58,0xa6,0x60,0x12,0x9e,0x08,
0xfd,0x73,0x69,0x43,0xfb,0x19,0x43,0xa5,
0x57,0x20,0xb9,0xe0,0x95,0x7b,0x1e,0xd6,
0x73,0x48,0x16,0x61,0x9f,0x13,0x88,0xf4,
0x3f,0x73,0xe6,0xe3,0xba,0xa8,0x1c,0x0e
};
static const byte msgPh[] = {
0x61,0x62,0x63
};
/* SHA-512 hash of msgPh */
static const byte hashPh[] = {
0xdd,0xaf,0x35,0xa1,0x93,0x61,0x7a,0xba,
0xcc,0x41,0x73,0x49,0xae,0x20,0x41,0x31,
0x12,0xe6,0xfa,0x4e,0x89,0xa9,0x7e,0xa2,
0x0a,0x9e,0xee,0xe6,0x4b,0x55,0xd3,0x9a,
0x21,0x92,0x99,0x2a,0x27,0x4f,0xc1,0xa8,
0x36,0xba,0x3c,0x23,0xa3,0xfe,0xeb,0xbd,
0x45,0x4d,0x44,0x23,0x64,0x3c,0xe8,0x0e,
0x2a,0x9a,0xc9,0x4f,0xa5,0x4c,0xa4,0x9f
};
static const byte contextPh2[] = {
0x66,0x6f,0x6f
};
outlen = sizeof(out);
XMEMSET(out, 0, sizeof(out));
if (wc_ed25519_import_private_key(sKeyPh, ED25519_KEY_SIZE, pKeyPh,
sizeof(pKeyPh), &key) != 0) {
return -9030;
}
if (wc_ed25519ph_sign_msg(msgPh, sizeof(msgPh), out, &outlen, &key, NULL,
0) != 0) {
return -9031;
}
if (XMEMCMP(out, sigPh1, 64))
return -9032;
#if defined(HAVE_ED25519_VERIFY)
/* test verify on good msg */
if (wc_ed25519ph_verify_msg(out, outlen, msgPh, sizeof(msgPh), &verify,
&key, NULL, 0) != 0 ||
verify != 1) {
return -9033;
}
#endif
if (wc_ed25519ph_sign_msg(msgPh, sizeof(msgPh), out, &outlen, &key,
contextPh2, sizeof(contextPh2)) != 0) {
return -9035;
}
if (XMEMCMP(out, sigPh2, 64))
return -9036;
#if defined(HAVE_ED25519_VERIFY)
/* test verify on good msg */
if (wc_ed25519ph_verify_msg(out, outlen, msgPh, sizeof(msgPh), &verify,
&key, contextPh2, sizeof(contextPh2)) != 0 ||
verify != 1) {
return -9037;
}
#endif
if (wc_ed25519ph_sign_hash(hashPh, sizeof(hashPh), out, &outlen, &key, NULL,
0) != 0) {
return -9041;
}
if (XMEMCMP(out, sigPh1, 64))
return -9042;
#if defined(HAVE_ED25519_VERIFY)
if (wc_ed25519ph_verify_hash(out, outlen, hashPh, sizeof(hashPh), &verify,
&key, NULL, 0) != 0 ||
verify != 1) {
return -9043;
}
#endif
if (wc_ed25519ph_sign_hash(hashPh, sizeof(hashPh), out, &outlen, &key,
contextPh2, sizeof(contextPh2)) != 0) {
return -9045;
}
if (XMEMCMP(out, sigPh2, 64))
return -9046;
#if defined(HAVE_ED25519_VERIFY)
if (wc_ed25519ph_verify_hash(out, outlen, hashPh, sizeof(hashPh), &verify,
&key, contextPh2, sizeof(contextPh2)) != 0 ||
verify != 1) {
return -9047;
}
#endif
wc_ed25519_free(&key);
return 0;
}
#endif /* HAVE_ED25519_SIGN && HAVE_ED25519_KEY_EXPORT && HAVE_ED25519_KEY_IMPORT */
int ed25519_test(void)
{
int ret;
@ -18916,6 +19158,14 @@ int ed25519_test(void)
#endif /* HAVE_ED25519_VERIFY */
}
ret = ed25519ctx_test();
if (ret != 0)
return ret;
ret = ed25519ph_test();
if (ret != 0)
return ret;
#ifndef NO_ASN
/* Try ASN.1 encoded private-only key and public key. */
idx = 0;

View File

@ -63,6 +63,12 @@
#define ED25519_PRV_KEY_SIZE (ED25519_PUB_KEY_SIZE+ED25519_KEY_SIZE)
enum {
Ed25519 = -1,
Ed25519ctx = 0,
Ed25519ph = 1,
};
#ifndef WC_ED25519KEY_TYPE_DEFINED
typedef struct ed25519_key ed25519_key;
#define WC_ED25519KEY_TYPE_DEFINED
@ -90,11 +96,35 @@ int wc_ed25519_make_public(ed25519_key* key, unsigned char* pubKey,
WOLFSSL_API
int wc_ed25519_make_key(WC_RNG* rng, int keysize, ed25519_key* key);
WOLFSSL_API
int wc_ed25519_sign_msg(const byte* in, word32 inlen, byte* out,
word32 *outlen, ed25519_key* key);
int wc_ed25519_sign_msg(const byte* in, word32 inLen, byte* out,
word32 *outLen, ed25519_key* key);
WOLFSSL_API
int wc_ed25519_verify_msg(const byte* sig, word32 siglen, const byte* msg,
word32 msglen, int* stat, ed25519_key* key);
int wc_ed25519ctx_sign_msg(const byte* in, word32 inLen, byte* out,
word32 *outLen, ed25519_key* key,
const byte* context, byte contextLen);
WOLFSSL_API
int wc_ed25519ph_sign_hash(const byte* hash, word32 hashLen, byte* out,
word32 *outLen, ed25519_key* key,
const byte* context, byte contextLen);
WOLFSSL_API
int wc_ed25519ph_sign_msg(const byte* in, word32 inLen, byte* out,
word32 *outLen, ed25519_key* key, const byte* context,
byte contextLen);
WOLFSSL_API
int wc_ed25519_verify_msg(const byte* sig, word32 sigLen, const byte* msg,
word32 msgLen, int* stat, ed25519_key* key);
WOLFSSL_API
int wc_ed25519ctx_verify_msg(const byte* sig, word32 sigLen, const byte* msg,
word32 msgLen, int* stat, ed25519_key* key,
const byte* context, byte contextLen);
WOLFSSL_API
int wc_ed25519ph_verify_hash(const byte* sig, word32 sigLen, const byte* hash,
word32 hashLen, int* stat, ed25519_key* key,
const byte* context, byte contextLen);
WOLFSSL_API
int wc_ed25519ph_verify_msg(const byte* sig, word32 sigLen, const byte* msg,
word32 msgLen, int* stat, ed25519_key* key,
const byte* context, byte contextLen);
WOLFSSL_API
int wc_ed25519_init(ed25519_key* key);
WOLFSSL_API