Skip to content

Commit

Permalink
libtomcrypt: add ed25519ctx and ed25519ph support
Browse files Browse the repository at this point in the history
Support contextualized extension of the Ed25519 scheme.

Signed-off-by: Valerii Chubar <[email protected]>
Signed-off-by: Sergiy Kibrik <[email protected]>
  • Loading branch information
Valerii Chubar authored and sa-kib committed Sep 12, 2022
1 parent 3ea147b commit 3dcdb3e
Show file tree
Hide file tree
Showing 8 changed files with 299 additions and 44 deletions.
26 changes: 22 additions & 4 deletions core/lib/libtomcrypt/src/headers/tomcrypt_pk.h
Original file line number Diff line number Diff line change
Expand Up @@ -368,10 +368,28 @@ int ed25519_import_pkcs8(const unsigned char *in, unsigned long inlen,
int ed25519_sign(const unsigned char *msg, unsigned long msglen,
unsigned char *sig, unsigned long *siglen,
const curve25519_key *private_key);

int ed25519_verify(const unsigned char *msg, unsigned long msglen,
const unsigned char *sig, unsigned long siglen,
int *stat, const curve25519_key *public_key);
int ed25519ctx_sign(const unsigned char *msg, unsigned long msglen,
unsigned char *sig, unsigned long *siglen,
const unsigned char *ctx, unsigned long ctxlen,
const curve25519_key *private_key);
int ed25519ph_sign(const unsigned char *msg, unsigned long msglen,
unsigned char *sig, unsigned long *siglen,
const unsigned char *ctx, unsigned long ctxlen,
const curve25519_key *private_key);
int ed25519_verify(const unsigned char *msg, unsigned long msglen,
const unsigned char *sig, unsigned long siglen,
int *stat,
const curve25519_key *public_key);
int ed25519ctx_verify(const unsigned char *msg, unsigned long msglen,
const unsigned char *sig, unsigned long siglen,
const unsigned char *ctx, unsigned long ctxlen,
int *stat,
const curve25519_key *public_key);
int ed25519ph_verify(const unsigned char *msg, unsigned long msglen,
const unsigned char *sig, unsigned long siglen,
const unsigned char *ctx, unsigned long ctxlen,
int *stat,
const curve25519_key *public_key);

/** X25519 Key-Exchange API */
int x25519_make_key(prng_state *prng, int wprng, curve25519_key *key);
Expand Down
9 changes: 7 additions & 2 deletions core/lib/libtomcrypt/src/headers/tomcrypt_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -334,17 +334,19 @@ int dsa_int_validate_primes(const dsa_key *key, int *stat);
int tweetnacl_crypto_sign(
unsigned char *sm,unsigned long long *smlen,
const unsigned char *m,unsigned long long mlen,
const unsigned char *sk, const unsigned char *pk);
const unsigned char *sk,const unsigned char *pk,
const unsigned char *ctx,unsigned long long cs);
int tweetnacl_crypto_sign_open(
int *stat,
unsigned char *m,unsigned long long *mlen,
const unsigned char *sm,unsigned long long smlen,
const unsigned char *ctx, unsigned long long cs,
const unsigned char *pk);
int tweetnacl_crypto_sign_keypair(prng_state *prng, int wprng, unsigned char *pk,unsigned char *sk);
int tweetnacl_crypto_sk_to_pk(unsigned char *pk, const unsigned char *sk);
int tweetnacl_crypto_scalarmult(unsigned char *q, const unsigned char *n, const unsigned char *p);
int tweetnacl_crypto_scalarmult_base(unsigned char *q,const unsigned char *n);

int tweetnacl_crypto_hash(unsigned char *out, const unsigned char *msg, unsigned long long n);
typedef int (*sk_to_pk)(unsigned char *pk ,const unsigned char *sk);
int ec25519_import_pkcs8(const unsigned char *in, unsigned long inlen,
const void *pwd, unsigned long pwdlen,
Expand All @@ -353,6 +355,9 @@ int ec25519_import_pkcs8(const unsigned char *in, unsigned long inlen,
int ec25519_export( unsigned char *out, unsigned long *outlen,
int which,
const curve25519_key *key);
int ec25519_crypto_ctx( unsigned char *out, unsigned long *outlen,
unsigned char flag,
const unsigned char *ctx, unsigned long ctxlen);
#endif /* LTC_CURVE25519 */

#ifdef LTC_DER
Expand Down
37 changes: 37 additions & 0 deletions core/lib/libtomcrypt/src/pk/ec25519/ec25519_crypto_ctx.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include "tomcrypt_private.h"

/**
@file ec25519_crypto_ctx.c
curve25519 crypto context helper
*/

#ifdef LTC_CURVE25519

int ec25519_crypto_ctx(unsigned char *out, unsigned long *outlen, unsigned char flag, const unsigned char *ctx, unsigned long ctxlen)
{
unsigned char *buf = out;

const char *prefix = "SigEd25519 no Ed25519 collisions";
const unsigned long prefix_len = strlen(prefix);
const unsigned char ctxlen8 = (unsigned char)ctxlen;

if (ctxlen > 255u) return CRYPT_INPUT_TOO_LONG;
if (*outlen < prefix_len + 2u + ctxlen) return CRYPT_BUFFER_OVERFLOW;

XMEMCPY(buf, prefix, prefix_len);
buf += prefix_len;
XMEMCPY(buf, &flag, 1);
buf++;
XMEMCPY(buf, &ctxlen8, 1);
buf++;
XMEMCPY(buf, ctx, ctxlen);
buf += ctxlen;

*outlen = buf-out;

return CRYPT_OK;
}

#endif
1 change: 1 addition & 0 deletions core/lib/libtomcrypt/src/pk/ec25519/sub.mk
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
srcs-y += ec25519_export.c
srcs-y += ec25519_crypto_ctx.c
srcs-y += tweetnacl.c
28 changes: 16 additions & 12 deletions core/lib/libtomcrypt/src/pk/ec25519/tweetnacl.c
Original file line number Diff line number Diff line change
Expand Up @@ -228,18 +228,22 @@ int tweetnacl_crypto_scalarmult_base(u8 *q,const u8 *n)
return tweetnacl_crypto_scalarmult(q,n,_9);
}

static int tweetnacl_crypto_hash(u8 *out,const u8 *m,u64 n)
static LTC_INLINE int tweetnacl_crypto_hash_ctx(u8 *out,const u8 *m,u64 n,const u8 *ctx,u32 cs)
{
unsigned long len;
int err, hash_idx;
unsigned long len = 64;
int hash_idx = find_hash("sha512");

if (n > ULONG_MAX) return CRYPT_OVERFLOW;

hash_idx = find_hash("sha512");
len = 64;
if ((err = hash_memory(hash_idx, m, n, out, &len)) != CRYPT_OK) return err;
if(cs == 0)
return hash_memory(hash_idx, m, n, out, &len);

return 0;
return hash_memory_multi(hash_idx, out, &len, ctx, cs, m, n, NULL);
}

int tweetnacl_crypto_hash(u8 *out,const u8 *m,u64 n)
{
return tweetnacl_crypto_hash_ctx(out, m, n, NULL, 0);
}

sv add(gf p[4],gf q[4])
Expand Down Expand Up @@ -383,7 +387,7 @@ sv reduce(u8 *r)
modL(r,x);
}

int tweetnacl_crypto_sign(u8 *sm,u64 *smlen,const u8 *m,u64 mlen,const u8 *sk,const u8 *pk)
int tweetnacl_crypto_sign(u8 *sm,u64 *smlen,const u8 *m,u64 mlen,const u8 *sk,const u8 *pk, const u8 *ctx, u64 cs)
{
u8 d[64],h[64],r[64];
i64 i,j,x[64];
Expand All @@ -398,13 +402,13 @@ int tweetnacl_crypto_sign(u8 *sm,u64 *smlen,const u8 *m,u64 mlen,const u8 *sk,co
FOR(i,(i64)mlen) sm[64 + i] = m[i];
FOR(i,32) sm[32 + i] = d[32 + i];

tweetnacl_crypto_hash(r, sm+32, mlen+32);
tweetnacl_crypto_hash_ctx(r, sm+32, mlen+32,ctx,cs);
reduce(r);
scalarbase(p,r);
pack(sm,p);

FOR(i,32) sm[i+32] = pk[i];
tweetnacl_crypto_hash(h,sm,mlen + 64);
tweetnacl_crypto_hash_ctx(h,sm,mlen + 64,ctx,cs);
reduce(h);

FOR(i,64) x[i] = 0;
Expand Down Expand Up @@ -451,7 +455,7 @@ static int unpackneg(gf r[4],const u8 p[32])
return 0;
}

int tweetnacl_crypto_sign_open(int *stat, u8 *m,u64 *mlen,const u8 *sm,u64 smlen,const u8 *pk)
int tweetnacl_crypto_sign_open(int *stat, u8 *m,u64 *mlen,const u8 *sm,u64 smlen,const u8 *ctx,u64 cs,const u8 *pk)
{
u64 i;
u8 s[32],t[32],h[64];
Expand All @@ -467,7 +471,7 @@ int tweetnacl_crypto_sign_open(int *stat, u8 *m,u64 *mlen,const u8 *sm,u64 smlen
XMEMMOVE(m,sm,smlen);
XMEMMOVE(s,m + 32,32);
XMEMMOVE(m + 32,pk,32);
tweetnacl_crypto_hash(h,m,smlen);
tweetnacl_crypto_hash_ctx(h,m,smlen,ctx,cs);
reduce(h);
scalarmult(p,q,h);

Expand Down
1 change: 0 additions & 1 deletion core/lib/libtomcrypt/src/pk/ed25519/ed25519_make_key.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ int ed25519_make_key(prng_state *prng, int wprng, curve25519_key *key)
{
int err;

LTC_ARGCHK(prng != NULL);
LTC_ARGCHK(key != NULL);

if ((err = tweetnacl_crypto_sign_keypair(prng, wprng, key->pub, key->priv)) != CRYPT_OK) {
Expand Down
117 changes: 105 additions & 12 deletions core/lib/libtomcrypt/src/pk/ed25519/ed25519_sign.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,10 @@

#ifdef LTC_CURVE25519

/**
Create an Ed25519 signature.
@param private_key The private Ed25519 key in the pair
@param public_key The public Ed25519 key in the pair
@param out [out] The destination of the shared data
@param outlen [in/out] The max size and resulting size of the shared data.
@return CRYPT_OK if successful
*/
int ed25519_sign(const unsigned char *msg, unsigned long msglen,
unsigned char *sig, unsigned long *siglen,
const curve25519_key *private_key)
static int s_ed25519_sign(const unsigned char *msg, unsigned long msglen,
unsigned char *sig, unsigned long *siglen,
const unsigned char *ctx, unsigned long ctxlen,
const curve25519_key *private_key)
{
unsigned char *s;
unsigned long long smlen;
Expand All @@ -51,7 +44,8 @@ int ed25519_sign(const unsigned char *msg, unsigned long msglen,

err = tweetnacl_crypto_sign(s, &smlen,
msg, msglen,
private_key->priv, private_key->pub);
private_key->priv, private_key->pub,
ctx, ctxlen);

XMEMCPY(sig, s, 64uL);
*siglen = 64uL;
Expand All @@ -64,6 +58,105 @@ int ed25519_sign(const unsigned char *msg, unsigned long msglen,
return err;
}

/**
Create an Ed25519ctx signature.
@param msg The data to be signed
@param msglen [in] The size of the date to be signed
@param sig [out] The destination of the shared data
@param siglen [in/out] The max size and resulting size of the shared data.
@param ctx [in] The context is a constant buffer
@param ctxlen [in] size of context buffer
@param private_key The private Ed25519 key in the pair
@return CRYPT_OK if successful
*/
int ed25519ctx_sign(const unsigned char *msg, unsigned long msglen,
unsigned char *sig, unsigned long *siglen,
const unsigned char *ctx, unsigned long ctxlen,
const curve25519_key *private_key)
{
int err;
unsigned char *ctx_prefix;
unsigned long ctx_prefix_size = 512;

LTC_ARGCHK(ctx != NULL);

ctx_prefix = XMALLOC(ctx_prefix_size);
if (ctx_prefix == NULL) return CRYPT_MEM;

if ((err = ec25519_crypto_ctx(ctx_prefix, &ctx_prefix_size, 0, ctx, ctxlen)) != CRYPT_OK)
goto LBL_ERR;

err = s_ed25519_sign(msg, msglen, sig, siglen, ctx_prefix, ctx_prefix_size, private_key);

LBL_ERR:
#ifdef LTC_CLEAN_STACK
zeromem(ctx_prefix, 512);
#endif
XFREE(ctx_prefix);

return err;
}

/**
Create an Ed25519ph signature.
@param msg The data to be signed
@param msglen [in] The size of the date to be signed
@param sig [out] The destination of the shared data
@param siglen [in/out] The max size and resulting size of the shared data.
@param ctx [in] The context is a constant buffer
@param ctxlen [in] size of context buffer
@param private_key The private Ed25519 key in the pair
@return CRYPT_OK if successful
*/
int ed25519ph_sign(const unsigned char *msg, unsigned long msglen,
unsigned char *sig, unsigned long *siglen,
const unsigned char *ctx, unsigned long ctxlen,
const curve25519_key *private_key)
{
int err;
unsigned char *ctx_prefix;
unsigned char msg_hash[64] = {0};
unsigned long ctx_prefix_size = 512;

ctx_prefix = XMALLOC(ctx_prefix_size);
if (ctx_prefix == NULL) return CRYPT_MEM;

if ((err = ec25519_crypto_ctx(ctx_prefix, &ctx_prefix_size, 1, ctx, ctxlen)) != CRYPT_OK)
goto LBL_ERR;

if ((err = tweetnacl_crypto_hash(msg_hash, msg, msglen)) != CRYPT_OK)
goto LBL_ERR;

msg = msg_hash;
msglen = 64;

err = s_ed25519_sign(msg, msglen, sig, siglen, ctx_prefix, ctx_prefix_size, private_key);

LBL_ERR:
#ifdef LTC_CLEAN_STACK
zeromem(ctx_prefix, 512);
#endif
XFREE(ctx_prefix);

return err;
}

/**
Create an Ed25519 signature.
@param msg The data to be signed
@param msglen [in] The size of the date to be signed
@param sig [out] The destination of the shared data
@param siglen [in/out] The max size and resulting size of the shared data.
@param private_key The private Ed25519 key in the pair
@return CRYPT_OK if successful
*/
int ed25519_sign(const unsigned char *msg, unsigned long msglen,
unsigned char *sig, unsigned long *siglen,
const curve25519_key *private_key)
{
return s_ed25519_sign(msg, msglen, sig, siglen, 0, 0, private_key);
}

#endif

/* ref: $Format:%D$ */
Expand Down
Loading

0 comments on commit 3dcdb3e

Please sign in to comment.