1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3 #include "tomcrypt_private.h"
4
5 /**
6 @file ed25519_verify.c
7 Verify an Ed25519 signature, Steffen Jaeckel
8 */
9
10 #ifdef LTC_CURVE25519
11
s_ed25519_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)12 static int s_ed25519_verify(const unsigned char *msg, unsigned long msglen,
13 const unsigned char *sig, unsigned long siglen,
14 const unsigned char *ctx, unsigned long ctxlen,
15 int *stat,
16 const curve25519_key *public_key)
17 {
18 unsigned char* m;
19 unsigned long long mlen;
20 int err;
21
22 LTC_ARGCHK(msg != NULL);
23 LTC_ARGCHK(sig != NULL);
24 LTC_ARGCHK(stat != NULL);
25 LTC_ARGCHK(public_key != NULL);
26
27 *stat = 0;
28
29 if (siglen != 64uL) return CRYPT_INVALID_ARG;
30 if (public_key->algo != LTC_OID_ED25519) return CRYPT_PK_INVALID_TYPE;
31
32 mlen = msglen + siglen;
33 if ((mlen < msglen) || (mlen < siglen)) return CRYPT_OVERFLOW;
34
35 m = XMALLOC(mlen);
36 if (m == NULL) return CRYPT_MEM;
37
38 XMEMCPY(m, sig, siglen);
39 XMEMCPY(m + siglen, msg, msglen);
40
41 err = tweetnacl_crypto_sign_open(stat,
42 m, &mlen,
43 m, mlen,
44 ctx, ctxlen,
45 public_key->pub);
46
47 #ifdef LTC_CLEAN_STACK
48 zeromem(m, msglen + siglen);
49 #endif
50 XFREE(m);
51
52 return err;
53 }
54
55 /**
56 Verify an Ed25519ctx signature.
57 @param msg [in] The data to be verified
58 @param msglen [in] The size of the data to be verified
59 @param sig [in] The signature to be verified
60 @param siglen [in] The size of the signature to be verified
61 @param ctx [in] The context
62 @param ctxlen [in] The size of the context
63 @param stat [out] The result of the signature verification, 1==valid, 0==invalid
64 @param public_key [in] The public Ed25519 key in the pair
65 @return CRYPT_OK if successful
66 */
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)67 int ed25519ctx_verify(const unsigned char *msg, unsigned long msglen,
68 const unsigned char *sig, unsigned long siglen,
69 const unsigned char *ctx, unsigned long ctxlen,
70 int *stat,
71 const curve25519_key *public_key)
72 {
73 unsigned char ctx_prefix[292];
74 unsigned long ctx_prefix_size = sizeof(ctx_prefix);
75
76 LTC_ARGCHK(ctx != NULL);
77
78 if (ec25519_crypto_ctx(ctx_prefix, &ctx_prefix_size, 0, ctx, ctxlen) != CRYPT_OK)
79 return CRYPT_INVALID_ARG;
80
81 return s_ed25519_verify(msg, msglen, sig, siglen, ctx_prefix, ctx_prefix_size, stat, public_key);
82 }
83
84 /**
85 Verify an Ed25519ph signature.
86 @param msg [in] The data to be verified
87 @param msglen [in] The size of the data to be verified
88 @param sig [in] The signature to be verified
89 @param siglen [in] The size of the signature to be verified
90 @param ctx [in] The context
91 @param ctxlen [in] The size of the context
92 @param stat [out] The result of the signature verification, 1==valid, 0==invalid
93 @param public_key [in] The public Ed25519 key in the pair
94 @return CRYPT_OK if successful
95 */
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)96 int ed25519ph_verify(const unsigned char *msg, unsigned long msglen,
97 const unsigned char *sig, unsigned long siglen,
98 const unsigned char *ctx, unsigned long ctxlen,
99 int *stat,
100 const curve25519_key *public_key)
101 {
102 int err;
103 unsigned char msg_hash[64];
104 unsigned char ctx_prefix[292];
105 unsigned long ctx_prefix_size = sizeof(ctx_prefix);
106
107 if ((err = ec25519_crypto_ctx(ctx_prefix, &ctx_prefix_size, 1, ctx, ctxlen)) != CRYPT_OK)
108 return err;
109
110 if ((err = tweetnacl_crypto_ph(msg_hash, msg, msglen)) != CRYPT_OK)
111 return err;
112
113 return s_ed25519_verify(msg_hash, sizeof(msg_hash), sig, siglen, ctx_prefix, ctx_prefix_size, stat, public_key);
114 }
115
116 /**
117 Verify an Ed25519 signature.
118 @param msg [in] The data to be verified
119 @param msglen [in] The size of the data to be verified
120 @param sig [in] The signature to be verified
121 @param siglen [in] The size of the signature to be verified
122 @param stat [out] The result of the signature verification, 1==valid, 0==invalid
123 @param public_key [in] The public Ed25519 key in the pair
124 @return CRYPT_OK if successful
125 */
ed25519_verify(const unsigned char * msg,unsigned long msglen,const unsigned char * sig,unsigned long siglen,int * stat,const curve25519_key * public_key)126 int ed25519_verify(const unsigned char *msg, unsigned long msglen,
127 const unsigned char *sig, unsigned long siglen,
128 int *stat,
129 const curve25519_key *public_key)
130 {
131 return s_ed25519_verify(msg, msglen, sig, siglen, NULL, 0, stat, public_key);
132 }
133
134 #endif
135