Skip to content

Commit b761cc0

Browse files
Valerii Chubarsjaeckel
authored andcommitted
Add ed25519ctx and ed25519ph support
Signed-off-by: Valerii Chubar <[email protected]> Signed-off-by: Sergiy Kibrik <[email protected]>
1 parent a6c6492 commit b761cc0

File tree

6 files changed

+405
-33
lines changed

6 files changed

+405
-33
lines changed

src/headers/tomcrypt_pk.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,10 +358,23 @@ int ed25519_import_pkcs8(const unsigned char *in, unsigned long inlen,
358358
int ed25519_sign(const unsigned char *msg, unsigned long msglen,
359359
unsigned char *sig, unsigned long *siglen,
360360
const curve25519_key *private_key);
361-
361+
int ed25519ctx_sign(const unsigned char *msg, unsigned long msglen,
362+
unsigned char *sig, unsigned long *siglen,
363+
const char* ctx, const curve25519_key *private_key);
364+
int ed25519ph_sign(const unsigned char *msg, unsigned long msglen,
365+
unsigned char *sig, unsigned long *siglen,
366+
const char *ctx, const curve25519_key *private_key);
362367
int ed25519_verify(const unsigned char *msg, unsigned long msglen,
363368
const unsigned char *sig, unsigned long siglen,
364369
int *stat, const curve25519_key *public_key);
370+
int ed25519ctx_verify(const unsigned char *msg, unsigned long msglen,
371+
const unsigned char *sig, unsigned long siglen,
372+
int *stat, const char* ctx,
373+
const curve25519_key *public_key);
374+
int ed25519ph_verify(const unsigned char *msg, unsigned long msglen,
375+
const unsigned char *sig, unsigned long siglen,
376+
int *stat, const char* ctx,
377+
const curve25519_key *public_key);
365378

366379
/** X25519 Key-Exchange API */
367380
int x25519_make_key(prng_state *prng, int wprng, curve25519_key *key);

src/headers/tomcrypt_private.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
#define LTC_PAD_MASK (0xF000U)
1111

12+
#define ED25519_CONTEXT_PREFIX "SigEd25519 no Ed25519 collisions"
13+
1214
/*
1315
* Internal Enums
1416
*/
@@ -331,16 +333,21 @@ int dsa_int_validate_primes(const dsa_key *key, int *stat);
331333
int tweetnacl_crypto_sign(
332334
unsigned char *sm,unsigned long long *smlen,
333335
const unsigned char *m,unsigned long long mlen,
334-
const unsigned char *sk, const unsigned char *pk);
336+
const unsigned char *sk,const unsigned char *pk,
337+
const unsigned char *ctx,unsigned long long cs);
335338
int tweetnacl_crypto_sign_open(
336339
int *stat,
337340
unsigned char *m,unsigned long long *mlen,
338341
const unsigned char *sm,unsigned long long smlen,
342+
const unsigned char *ctx, unsigned long cs,
339343
const unsigned char *pk);
340344
int tweetnacl_crypto_sign_keypair(prng_state *prng, int wprng, unsigned char *pk,unsigned char *sk);
341345
int tweetnacl_crypto_sk_to_pk(unsigned char *pk, const unsigned char *sk);
342346
int tweetnacl_crypto_scalarmult(unsigned char *q, const unsigned char *n, const unsigned char *p);
343347
int tweetnacl_crypto_scalarmult_base(unsigned char *q,const unsigned char *n);
348+
int tweetnacl_crypto_ph(unsigned char *out, const unsigned char *msg, unsigned long msglen);
349+
int tweetnacl_crypto_ctx(unsigned char *out, unsigned long *outlen,
350+
unsigned char flag, const char *pr, const char* ctx);
344351

345352
typedef int (*sk_to_pk)(unsigned char *pk ,const unsigned char *sk);
346353
int ec25519_import_pkcs8(const unsigned char *in, unsigned long inlen,

src/pk/ec25519/tweetnacl.c

Lines changed: 66 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,27 @@ static int tweetnacl_crypto_hash(u8 *out,const u8 *m,u64 n)
235235
return 0;
236236
}
237237

238+
static int tweetnacl_crypto_hash_ctx(u8 *out,const u8 *m,u64 n,const u8 *ctx,u32 cs)
239+
{
240+
unsigned long len;
241+
int err;
242+
u8 buf[512];
243+
244+
if(cs == 0)
245+
return tweetnacl_crypto_hash(out,m,n);
246+
247+
len = n + cs;
248+
if (len > 512) return CRYPT_HASH_OVERFLOW;
249+
250+
XMEMCPY(buf,ctx,cs);
251+
XMEMCPY(buf+cs,m,n);
252+
253+
err = tweetnacl_crypto_hash(out,buf,len);
254+
zeromem(buf, len);
255+
256+
return err;
257+
}
258+
238259
sv add(gf p[4],gf q[4])
239260
{
240261
gf a,b,c,d,t,e,f,g,h;
@@ -376,7 +397,7 @@ sv reduce(u8 *r)
376397
modL(r,x);
377398
}
378399

379-
int tweetnacl_crypto_sign(u8 *sm,u64 *smlen,const u8 *m,u64 mlen,const u8 *sk,const u8 *pk)
400+
int tweetnacl_crypto_sign(u8 *sm,u64 *smlen,const u8 *m,u64 mlen,const u8 *sk,const u8 *pk, const u8 *ctx, u64 cs)
380401
{
381402
u8 d[64],h[64],r[64];
382403
i64 i,j,x[64];
@@ -391,13 +412,13 @@ int tweetnacl_crypto_sign(u8 *sm,u64 *smlen,const u8 *m,u64 mlen,const u8 *sk,co
391412
FOR(i,(i64)mlen) sm[64 + i] = m[i];
392413
FOR(i,32) sm[32 + i] = d[32 + i];
393414

394-
tweetnacl_crypto_hash(r, sm+32, mlen+32);
415+
tweetnacl_crypto_hash_ctx(r, sm+32, mlen+32,ctx,cs);
395416
reduce(r);
396417
scalarbase(p,r);
397418
pack(sm,p);
398419

399420
FOR(i,32) sm[i+32] = pk[i];
400-
tweetnacl_crypto_hash(h,sm,mlen + 64);
421+
tweetnacl_crypto_hash_ctx(h,sm,mlen + 64,ctx,cs);
401422
reduce(h);
402423

403424
FOR(i,64) x[i] = 0;
@@ -444,7 +465,7 @@ static int unpackneg(gf r[4],const u8 p[32])
444465
return 0;
445466
}
446467

447-
int tweetnacl_crypto_sign_open(int *stat, u8 *m,u64 *mlen,const u8 *sm,u64 smlen,const u8 *pk)
468+
int tweetnacl_crypto_sign_open(int *stat, u8 *m,u64 *mlen,const u8 *sm,u64 smlen,const u8 *ctx,size_t cs,const u8 *pk)
448469
{
449470
u64 i;
450471
u8 s[32],t[32],h[64];
@@ -460,7 +481,7 @@ int tweetnacl_crypto_sign_open(int *stat, u8 *m,u64 *mlen,const u8 *sm,u64 smlen
460481
XMEMMOVE(m,sm,smlen);
461482
XMEMMOVE(s,m + 32,32);
462483
XMEMMOVE(m + 32,pk,32);
463-
tweetnacl_crypto_hash(h,m,smlen);
484+
tweetnacl_crypto_hash_ctx(h,m,smlen,ctx,cs);
464485
reduce(h);
465486
scalarmult(p,q,h);
466487

@@ -480,3 +501,43 @@ int tweetnacl_crypto_sign_open(int *stat, u8 *m,u64 *mlen,const u8 *sm,u64 smlen
480501
*mlen = smlen;
481502
return CRYPT_OK;
482503
}
504+
505+
int tweetnacl_crypto_ph(u8 *out,const u8 *msg,size_t msglen)
506+
{
507+
hash_state md;
508+
509+
sha512_init(&md);
510+
511+
if(sha512_process(&md, msg, msglen) != CRYPT_OK)
512+
return CRYPT_INVALID_ARG;
513+
514+
if(sha512_done(&md, out) != CRYPT_OK)
515+
return CRYPT_INVALID_ARG;
516+
517+
return CRYPT_OK;
518+
}
519+
520+
int tweetnacl_crypto_ctx(u8 *out,size_t *outlen,u8 flag,const char *pr, const char *ctx)
521+
{
522+
u8 *buf = out;
523+
const int ctx_prefix_len = strlen(pr);
524+
const int ctxlen = ctx ? strlen(ctx) : 0;
525+
526+
if(ctxlen > 255) return CRYPT_INPUT_TOO_LONG;
527+
528+
XMEMCPY(buf, pr, ctx_prefix_len);
529+
buf += ctx_prefix_len;
530+
XMEMCPY(buf, &flag, 1);
531+
buf++;
532+
XMEMCPY(buf, &ctxlen, 1);
533+
buf++;
534+
535+
if(ctxlen > 0) {
536+
XMEMCPY(buf, ctx, ctxlen);
537+
buf += ctxlen;
538+
}
539+
540+
*outlen = buf-out;
541+
542+
return CRYPT_OK;
543+
}

src/pk/ed25519/ed25519_sign.c

Lines changed: 81 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,10 @@
99

1010
#ifdef LTC_CURVE25519
1111

12-
/**
13-
Create an Ed25519 signature.
14-
@param private_key The private Ed25519 key in the pair
15-
@param public_key The public Ed25519 key in the pair
16-
@param out [out] The destination of the shared data
17-
@param outlen [in/out] The max size and resulting size of the shared data.
18-
@return CRYPT_OK if successful
19-
*/
20-
int ed25519_sign(const unsigned char *msg, unsigned long msglen,
21-
unsigned char *sig, unsigned long *siglen,
22-
const curve25519_key *private_key)
12+
static int ed25519_sign_private(const unsigned char *msg, unsigned long msglen,
13+
unsigned char *sig, unsigned long *siglen,
14+
const char* ctx, unsigned long ctxlen,
15+
const curve25519_key *private_key)
2316
{
2417
unsigned char *s;
2518
unsigned long long smlen;
@@ -44,7 +37,8 @@ int ed25519_sign(const unsigned char *msg, unsigned long msglen,
4437

4538
err = tweetnacl_crypto_sign(s, &smlen,
4639
msg, msglen,
47-
private_key->priv, private_key->pub);
40+
private_key->priv, private_key->pub,
41+
ctx, ctxlen);
4842

4943
XMEMCPY(sig, s, 64uL);
5044
*siglen = 64uL;
@@ -57,4 +51,79 @@ int ed25519_sign(const unsigned char *msg, unsigned long msglen,
5751
return err;
5852
}
5953

54+
/**
55+
Create an Ed25519ctx signature.
56+
@param msg The data to be signed
57+
@param msglen [in] The size of the date to be signed
58+
@param sig [out] The destination of the shared data
59+
@param siglen [in/out] The max size and resulting size of the shared data.
60+
@param ctx [in] The context is a constant null terminated string
61+
@param private_key The private Ed25519 key in the pair
62+
@return CRYPT_OK if successful
63+
*/
64+
int ed25519ctx_sign(const unsigned char *msg, unsigned long msglen,
65+
unsigned char *sig, unsigned long *siglen,
66+
const char* ctx, const curve25519_key *private_key)
67+
{
68+
unsigned char ctx_prefix[512] = {0};
69+
unsigned long ctx_prefix_size = 0;
70+
71+
LTC_ARGCHK(ctx != NULL);
72+
73+
if(tweetnacl_crypto_ctx(ctx_prefix, &ctx_prefix_size, 0,
74+
ED25519_CONTEXT_PREFIX, ctx) != CRYPT_OK)
75+
return CRYPT_INVALID_ARG;
76+
77+
return ed25519_sign_private(msg, msglen, sig, siglen, ctx_prefix,
78+
ctx_prefix_size, private_key);
79+
}
80+
81+
/**
82+
Create an Ed25519ph signature.
83+
@param msg The data to be signed
84+
@param msglen [in] The size of the date to be signed
85+
@param sig [out] The destination of the shared data
86+
@param siglen [in/out] The max size and resulting size of the shared data.
87+
@param ctx [in] The context is a constant null terminated string
88+
@param private_key The private Ed25519 key in the pair
89+
@return CRYPT_OK if successful
90+
*/
91+
int ed25519ph_sign(const unsigned char *msg, unsigned long msglen,
92+
unsigned char *sig, unsigned long *siglen,
93+
const char *ctx, const curve25519_key *private_key)
94+
{
95+
unsigned char ctx_prefix[512] = {0};
96+
unsigned char msg_hash[64] = {0};
97+
unsigned long ctx_prefix_size = 0;
98+
99+
if (tweetnacl_crypto_ctx(ctx_prefix, &ctx_prefix_size, 1,
100+
ED25519_CONTEXT_PREFIX, ctx) != CRYPT_OK)
101+
return CRYPT_INVALID_ARG;
102+
103+
if (tweetnacl_crypto_ph(msg_hash, msg, msglen) != CRYPT_OK)
104+
return CRYPT_INVALID_ARG;
105+
106+
msg = msg_hash;
107+
msglen = 64;
108+
109+
return ed25519_sign_private(msg, msglen, sig, siglen, ctx_prefix,
110+
ctx_prefix_size, private_key);
111+
}
112+
113+
/**
114+
Create an Ed25519 signature.
115+
@param msg The data to be signed
116+
@param msglen [in] The size of the date to be signed
117+
@param sig [out] The destination of the shared data
118+
@param siglen [in/out] The max size and resulting size of the shared data.
119+
@param private_key The private Ed25519 key in the pair
120+
@return CRYPT_OK if successful
121+
*/
122+
int ed25519_sign(const unsigned char *msg, unsigned long msglen,
123+
unsigned char *sig, unsigned long *siglen,
124+
const curve25519_key *private_key)
125+
{
126+
return ed25519_sign_private(msg, msglen, sig, siglen, 0, 0, private_key);
127+
}
128+
60129
#endif

0 commit comments

Comments
 (0)