eddsa.c
Go to the documentation of this file.
1 /**
2  * @file eddsa.c
3  * @brief EdDSA (Edwards-Curve Digital Signature Algorithm)
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2024 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneCRYPTO Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.4.4
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL
33 
34 //Dependencies
35 #include "core/crypto.h"
36 #include "ecc/eddsa.h"
37 #include "mpi/mpi.h"
38 #include "debug.h"
39 
40 //Check crypto library configuration
41 #if (ED25519_SUPPORT == ENABLED || ED448_SUPPORT == ENABLED)
42 
43 
44 /**
45  * @brief Initialize an EdDSA public key
46  * @param[in] key Pointer to the EdDSA public key to initialize
47  **/
48 
50 {
51  //Initialize multiple precision integer
52  mpiInit(&key->q);
53 }
54 
55 
56 /**
57  * @brief Release an EdDSA public key
58  * @param[in] key Pointer to the EdDSA public key to free
59  **/
60 
62 {
63  //Free multiple precision integer
64  mpiFree(&key->q);
65 }
66 
67 
68 /**
69  * @brief Initialize an EdDSA private key
70  * @param[in] key Pointer to the EdDSA private key to initialize
71  **/
72 
74 {
75  //Initialize multiple precision integers
76  mpiInit(&key->d);
77  mpiInit(&key->q);
78 
79  //Initialize private key slot
80  key->slot = -1;
81 }
82 
83 
84 /**
85  * @brief Release an EdDSA private key
86  * @param[in] key Pointer to the EdDSA public key to free
87  **/
88 
90 {
91  //Free multiple precision integers
92  mpiFree(&key->d);
93  mpiFree(&key->q);
94 }
95 
96 
97 /**
98  * @brief EdDSA key pair generation
99  * @param[in] prngAlgo PRNG algorithm
100  * @param[in] prngContext Pointer to the PRNG context
101  * @param[in] curveInfo Elliptic curve parameters
102  * @param[out] privateKey EdDSA private key
103  * @param[out] publicKey EdDSA public key
104  * @return Error code
105  **/
106 
107 error_t eddsaGenerateKeyPair(const PrngAlgo *prngAlgo, void *prngContext,
108  const EcCurveInfo *curveInfo, EddsaPrivateKey *privateKey,
109  EddsaPublicKey *publicKey)
110 {
111  error_t error;
112 
113  //Generate a private key
114  error = eddsaGeneratePrivateKey(prngAlgo, prngContext, curveInfo,
115  privateKey);
116 
117  //Check status code
118  if(!error)
119  {
120  //Derive the public key from the private key
121  error = eddsaGeneratePublicKey(curveInfo, privateKey, publicKey);
122  }
123 
124  //Return status code
125  return error;
126 }
127 
128 
129 /**
130  * @brief EdDSA private key generation
131  * @param[in] prngAlgo PRNG algorithm
132  * @param[in] prngContext Pointer to the PRNG context
133  * @param[in] curveInfo Elliptic curve parameters
134  * @param[out] privateKey EdDSA private key
135  * @return Error code
136  **/
137 
138 error_t eddsaGeneratePrivateKey(const PrngAlgo *prngAlgo, void *prngContext,
139  const EcCurveInfo *curveInfo, EddsaPrivateKey *privateKey)
140 {
141  error_t error;
142 
143 #if (ED25519_SUPPORT == ENABLED)
144  //Ed25519 algorithm?
145  if(curveInfo == ED25519_CURVE)
146  {
147  uint8_t rawPrivateKey[ED25519_PRIVATE_KEY_LEN];
148 
149  //Generate an Ed25519 private key
150  error = ed25519GeneratePrivateKey(prngAlgo, prngContext, rawPrivateKey);
151 
152  //Check status code
153  if(!error)
154  {
155  //Import the Ed25519 private key
156  error = mpiImport(&privateKey->d, rawPrivateKey, ED25519_PRIVATE_KEY_LEN,
158  }
159  }
160  else
161 #endif
162 #if (ED448_SUPPORT == ENABLED)
163  //Ed448 algorithm?
164  if(curveInfo == ED448_CURVE)
165  {
166  uint8_t rawPrivateKey[ED448_PRIVATE_KEY_LEN];
167 
168  //Generate an Ed448 private key
169  error = ed448GeneratePrivateKey(prngAlgo, prngContext, rawPrivateKey);
170 
171  //Check status code
172  if(!error)
173  {
174  //Import the Ed448 private key
175  error = mpiImport(&privateKey->d, rawPrivateKey, ED448_PRIVATE_KEY_LEN,
177  }
178  }
179  else
180 #endif
181  //Unknown algorithm?
182  {
183  //Report an error
184  error = ERROR_INVALID_PARAMETER;
185  }
186 
187  //Return status code
188  return error;
189 }
190 
191 
192 /**
193  * @brief Derive the public key from an EdDSA private key
194  * @param[in] curveInfo Elliptic curve parameters
195  * @param[in] privateKey EdDSA private key
196  * @param[out] publicKey EdDSA public key
197  * @return Error code
198  **/
199 
201  const EddsaPrivateKey *privateKey, EddsaPublicKey *publicKey)
202 {
203  error_t error;
204 
205 #if (ED25519_SUPPORT == ENABLED)
206  //Ed25519 algorithm?
207  if(curveInfo == ED25519_CURVE)
208  {
209  uint8_t rawPrivateKey[ED25519_PRIVATE_KEY_LEN];
210  uint8_t rawPublicKey[ED25519_PUBLIC_KEY_LEN];
211 
212  //Export the Ed25519 private key
213  error = mpiExport(&privateKey->d, rawPrivateKey, ED25519_PRIVATE_KEY_LEN,
215 
216  //Check status code
217  if(!error)
218  {
219  //Derive the public key from the private key
220  error = ed25519GeneratePublicKey(rawPrivateKey, rawPublicKey);
221  }
222 
223  //Check status code
224  if(!error)
225  {
226  //Import the Ed25519 public key
227  error = mpiImport(&publicKey->q, rawPublicKey, ED25519_PUBLIC_KEY_LEN,
229  }
230  }
231  else
232 #endif
233 #if (ED448_SUPPORT == ENABLED)
234  //Ed448 algorithm?
235  if(curveInfo == ED448_CURVE)
236  {
237  uint8_t rawPrivateKey[ED448_PRIVATE_KEY_LEN];
238  uint8_t rawPublicKey[ED448_PUBLIC_KEY_LEN];
239 
240  //Export the Ed448 private key
241  error = mpiExport(&privateKey->d, rawPrivateKey, ED448_PRIVATE_KEY_LEN,
243 
244  //Check status code
245  if(!error)
246  {
247  //Derive the public key from the private key
248  error = ed448GeneratePublicKey(rawPrivateKey, rawPublicKey);
249  }
250 
251  //Check status code
252  if(!error)
253  {
254  //Import the Ed448 public key
255  error = mpiImport(&publicKey->q, rawPublicKey, ED448_PUBLIC_KEY_LEN,
257  }
258  }
259  else
260 #endif
261  //Unknown algorithm?
262  {
263  //Report an error
264  error = ERROR_INVALID_PARAMETER;
265  }
266 
267  //Return status code
268  return error;
269 }
270 
271 #endif
error_t ed448GeneratePrivateKey(const PrngAlgo *prngAlgo, void *prngContext, uint8_t *privateKey)
EdDSA private key generation.
Definition: ed448.c:131
#define PrngAlgo
Definition: crypto.h:938
#define ED25519_PUBLIC_KEY_LEN
Definition: ed25519.h:42
void eddsaFreePrivateKey(EddsaPrivateKey *key)
Release an EdDSA private key.
Definition: eddsa.c:89
void eddsaInitPrivateKey(EddsaPrivateKey *key)
Initialize an EdDSA private key.
Definition: eddsa.c:73
#define ED448_PUBLIC_KEY_LEN
Definition: ed448.h:42
#define ED25519_CURVE
Definition: ec_curves.h:260
#define ED448_CURVE
Definition: ec_curves.h:261
error_t mpiImport(Mpi *r, const uint8_t *data, uint_t length, MpiFormat format)
Octet string to integer conversion.
Definition: mpi.c:624
void mpiInit(Mpi *r)
Initialize a multiple precision integer.
Definition: mpi.c:48
#define ED25519_PRIVATE_KEY_LEN
Definition: ed25519.h:40
error_t eddsaGeneratePublicKey(const EcCurveInfo *curveInfo, const EddsaPrivateKey *privateKey, EddsaPublicKey *publicKey)
Derive the public key from an EdDSA private key.
Definition: eddsa.c:200
Elliptic curve parameters.
Definition: ec_curves.h:302
error_t mpiExport(const Mpi *a, uint8_t *data, uint_t length, MpiFormat format)
Integer to octet string conversion.
Definition: mpi.c:709
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
@ MPI_FORMAT_LITTLE_ENDIAN
Definition: mpi.h:70
error_t
Error codes.
Definition: error.h:43
error_t ed25519GeneratePrivateKey(const PrngAlgo *prngAlgo, void *prngContext, uint8_t *privateKey)
EdDSA private key generation.
Definition: ed25519.c:144
Mpi q
Public key.
Definition: eddsa.h:50
EdDSA public key.
Definition: eddsa.h:49
int_t slot
Private key slot.
Definition: eddsa.h:62
EdDSA (Edwards-Curve Digital Signature Algorithm)
MPI (Multiple Precision Integer Arithmetic)
Mpi q
Public key.
Definition: eddsa.h:61
General definitions for cryptographic algorithms.
error_t eddsaGenerateKeyPair(const PrngAlgo *prngAlgo, void *prngContext, const EcCurveInfo *curveInfo, EddsaPrivateKey *privateKey, EddsaPublicKey *publicKey)
EdDSA key pair generation.
Definition: eddsa.c:107
error_t ed448GeneratePublicKey(const uint8_t *privateKey, uint8_t *publicKey)
Derive the public key from an EdDSA private key.
Definition: ed448.c:155
EdDSA private key.
Definition: eddsa.h:59
#define ED448_PRIVATE_KEY_LEN
Definition: ed448.h:40
Mpi d
Private key.
Definition: eddsa.h:60
void eddsaFreePublicKey(EddsaPublicKey *key)
Release an EdDSA public key.
Definition: eddsa.c:61
error_t ed25519GeneratePublicKey(const uint8_t *privateKey, uint8_t *publicKey)
Derive the public key from an EdDSA private key.
Definition: ed25519.c:168
error_t eddsaGeneratePrivateKey(const PrngAlgo *prngAlgo, void *prngContext, const EcCurveInfo *curveInfo, EddsaPrivateKey *privateKey)
EdDSA private key generation.
Definition: eddsa.c:138
void eddsaInitPublicKey(EddsaPublicKey *key)
Initialize an EdDSA public key.
Definition: eddsa.c:49
Debugging facilities.
void mpiFree(Mpi *r)
Release a multiple precision integer.
Definition: mpi.c:64