ndn-lite
uECC.h
Go to the documentation of this file.
1 /* Copyright 2014, Kenneth MacKay. Licensed under the BSD 2-clause license. */
2 
3 #ifndef _UECC_H_
4 #define _UECC_H_
5 
6 #include <stdint.h>
7 
8 /* Platform selection options.
9 If uECC_PLATFORM is not defined, the code will try to guess it based on compiler macros.
10 Possible values for uECC_PLATFORM are defined below: */
11 #define uECC_arch_other 0
12 #define uECC_x86 1
13 #define uECC_x86_64 2
14 #define uECC_arm 3
15 #define uECC_arm_thumb 4
16 #define uECC_arm_thumb2 5
17 #define uECC_arm64 6
18 #define uECC_avr 7
19 
20 /* If desired, you can define uECC_WORD_SIZE as appropriate for your platform (1, 4, or 8 bytes).
21 If uECC_WORD_SIZE is not explicitly defined then it will be automatically set based on your
22 platform. */
23 
24 /* Optimization level; trade speed for code size.
25  Larger values produce code that is faster but larger.
26  Currently supported values are 0 - 4; 0 is unusably slow for most applications.
27  Optimization level 4 currently only has an effect ARM platforms where more than one
28  curve is enabled. */
29 #ifndef uECC_OPTIMIZATION_LEVEL
30  #define uECC_OPTIMIZATION_LEVEL 2
31 #endif
32 
33 /* uECC_SQUARE_FUNC - If enabled (defined as nonzero), this will cause a specific function to be
34 used for (scalar) squaring instead of the generic multiplication function. This can make things
35 faster somewhat faster, but increases the code size. */
36 #ifndef uECC_SQUARE_FUNC
37  #define uECC_SQUARE_FUNC 0
38 #endif
39 
40 /* uECC_VLI_NATIVE_LITTLE_ENDIAN - If enabled (defined as nonzero), this will switch to native
41 little-endian format for *all* arrays passed in and out of the public API. This includes public
42 and private keys, shared secrets, signatures and message hashes.
43 Using this switch reduces the amount of call stack memory used by uECC, since less intermediate
44 translations are required.
45 Note that this will *only* work on native little-endian processors and it will treat the uint8_t
46 arrays passed into the public API as word arrays, therefore requiring the provided byte arrays
47 to be word aligned on architectures that do not support unaligned accesses.
48 IMPORTANT: Keys and signatures generated with uECC_VLI_NATIVE_LITTLE_ENDIAN=1 are incompatible
49 with keys and signatures generated with uECC_VLI_NATIVE_LITTLE_ENDIAN=0; all parties must use
50 the same endianness. */
51 #define uECC_VLI_NATIVE_LITTLE_ENDIAN 0
52 #ifndef uECC_VLI_NATIVE_LITTLE_ENDIAN
53  #define uECC_VLI_NATIVE_LITTLE_ENDIAN 0
54 #endif
55 
56 /* Curve support selection. Set to 0 to remove that curve. */
57 #ifndef uECC_SUPPORTS_secp160r1
58  #define uECC_SUPPORTS_secp160r1 1
59 #endif
60 #ifndef uECC_SUPPORTS_secp192r1
61  #define uECC_SUPPORTS_secp192r1 1
62 #endif
63 #ifndef uECC_SUPPORTS_secp224r1
64  #define uECC_SUPPORTS_secp224r1 1
65 #endif
66 #ifndef uECC_SUPPORTS_secp256r1
67  #define uECC_SUPPORTS_secp256r1 1
68 #endif
69 #ifndef uECC_SUPPORTS_secp256k1
70  #define uECC_SUPPORTS_secp256k1 1
71 #endif
72 
73 /* Specifies whether compressed point format is supported.
74  Set to 0 to disable point compression/decompression functions. */
75 #ifndef uECC_SUPPORT_COMPRESSED_POINT
76  #define uECC_SUPPORT_COMPRESSED_POINT 1
77 #endif
78 
79 struct uECC_Curve_t;
80 typedef const struct uECC_Curve_t * uECC_Curve;
81 
82 #ifdef __cplusplus
83 extern "C"
84 {
85 #endif
86 
87 #if uECC_SUPPORTS_secp160r1
89 #endif
90 #if uECC_SUPPORTS_secp192r1
92 #endif
93 #if uECC_SUPPORTS_secp224r1
95 #endif
96 #if uECC_SUPPORTS_secp256r1
98 #endif
99 #if uECC_SUPPORTS_secp256k1
101 #endif
102 
103 /* uECC_RNG_Function type
104 The RNG function should fill 'size' random bytes into 'dest'. It should return 1 if
105 'dest' was filled with random data, or 0 if the random data could not be generated.
106 The filled-in values should be either truly random, or from a cryptographically-secure PRNG.
107 
108 A correctly functioning RNG function must be set (using uECC_set_rng()) before calling
109 uECC_make_key() or uECC_sign().
110 
111 Setting a correctly functioning RNG function improves the resistance to side-channel attacks
112 for uECC_shared_secret() and uECC_sign_deterministic().
113 
114 A correct RNG function is set by default when building for Windows, Linux, or OS X.
115 If you are building on another POSIX-compliant system that supports /dev/random or /dev/urandom,
116 you can define uECC_POSIX to use the predefined RNG. For embedded platforms there is no predefined
117 RNG function; you must provide your own.
118 */
119 typedef int (*uECC_RNG_Function)(uint8_t *dest, unsigned size);
120 
121 /* uECC_set_rng() function.
122 Set the function that will be used to generate random bytes. The RNG function should
123 return 1 if the random data was generated, or 0 if the random data could not be generated.
124 
125 On platforms where there is no predefined RNG function (eg embedded platforms), this must
126 be called before uECC_make_key() or uECC_sign() are used.
127 
128 Inputs:
129  rng_function - The function that will be used to generate random bytes.
130 */
131 void uECC_set_rng(uECC_RNG_Function rng_function);
132 
133 /* uECC_get_rng() function.
134 
135 Returns the function that will be used to generate random bytes.
136 */
138 
139 /* uECC_curve_private_key_size() function.
140 
141 Returns the size of a private key for the curve in bytes.
142 */
144 
145 /* uECC_curve_public_key_size() function.
146 
147 Returns the size of a public key for the curve in bytes.
148 */
150 
151 /* uECC_make_key() function.
152 Create a public/private key pair.
153 
154 Outputs:
155  public_key - Will be filled in with the public key. Must be at least 2 * the curve size
156  (in bytes) long. For example, if the curve is secp256r1, public_key must be 64
157  bytes long.
158  private_key - Will be filled in with the private key. Must be as long as the curve order; this
159  is typically the same as the curve size, except for secp160r1. For example, if the
160  curve is secp256r1, private_key must be 32 bytes long.
161 
162  For secp160r1, private_key must be 21 bytes long! Note that the first byte will
163  almost always be 0 (there is about a 1 in 2^80 chance of it being non-zero).
164 
165 Returns 1 if the key pair was generated successfully, 0 if an error occurred.
166 */
167 int uECC_make_key(uint8_t *public_key, uint8_t *private_key, uECC_Curve curve);
168 
169 /* uECC_shared_secret() function.
170 Compute a shared secret given your secret key and someone else's public key.
171 Note: It is recommended that you hash the result of uECC_shared_secret() before using it for
172 symmetric encryption or HMAC.
173 
174 Inputs:
175  public_key - The public key of the remote party.
176  private_key - Your private key.
177 
178 Outputs:
179  secret - Will be filled in with the shared secret value. Must be the same size as the
180  curve size; for example, if the curve is secp256r1, secret must be 32 bytes long.
181 
182 Returns 1 if the shared secret was generated successfully, 0 if an error occurred.
183 */
184 int uECC_shared_secret(const uint8_t *public_key,
185  const uint8_t *private_key,
186  uint8_t *secret,
187  uECC_Curve curve);
188 
189 #if uECC_SUPPORT_COMPRESSED_POINT
190 /* uECC_compress() function.
191 Compress a public key.
192 
193 Inputs:
194  public_key - The public key to compress.
195 
196 Outputs:
197  compressed - Will be filled in with the compressed public key. Must be at least
198  (curve size + 1) bytes long; for example, if the curve is secp256r1,
199  compressed must be 33 bytes long.
200 */
201 void uECC_compress(const uint8_t *public_key, uint8_t *compressed, uECC_Curve curve);
202 
203 /* uECC_decompress() function.
204 Decompress a compressed public key.
205 
206 Inputs:
207  compressed - The compressed public key.
208 
209 Outputs:
210  public_key - Will be filled in with the decompressed public key.
211 */
212 void uECC_decompress(const uint8_t *compressed, uint8_t *public_key, uECC_Curve curve);
213 #endif /* uECC_SUPPORT_COMPRESSED_POINT */
214 
215 /* uECC_valid_public_key() function.
216 Check to see if a public key is valid.
217 
218 Note that you are not required to check for a valid public key before using any other uECC
219 functions. However, you may wish to avoid spending CPU time computing a shared secret or
220 verifying a signature using an invalid public key.
221 
222 Inputs:
223  public_key - The public key to check.
224 
225 Returns 1 if the public key is valid, 0 if it is invalid.
226 */
227 int uECC_valid_public_key(const uint8_t *public_key, uECC_Curve curve);
228 
229 /* uECC_compute_public_key() function.
230 Compute the corresponding public key for a private key.
231 
232 Inputs:
233  private_key - The private key to compute the public key for
234 
235 Outputs:
236  public_key - Will be filled in with the corresponding public key
237 
238 Returns 1 if the key was computed successfully, 0 if an error occurred.
239 */
240 int uECC_compute_public_key(const uint8_t *private_key, uint8_t *public_key, uECC_Curve curve);
241 
242 /* uECC_sign() function.
243 Generate an ECDSA signature for a given hash value.
244 
245 Usage: Compute a hash of the data you wish to sign (SHA-2 is recommended) and pass it in to
246 this function along with your private key.
247 
248 Inputs:
249  private_key - Your private key.
250  message_hash - The hash of the message to sign.
251  hash_size - The size of message_hash in bytes.
252 
253 Outputs:
254  signature - Will be filled in with the signature value. Must be at least 2 * curve size long.
255  For example, if the curve is secp256r1, signature must be 64 bytes long.
256 
257 Returns 1 if the signature generated successfully, 0 if an error occurred.
258 */
259 int uECC_sign(const uint8_t *private_key,
260  const uint8_t *message_hash,
261  unsigned hash_size,
262  uint8_t *signature,
263  uECC_Curve curve);
264 
265 /* uECC_HashContext structure.
266 This is used to pass in an arbitrary hash function to uECC_sign_deterministic().
267 The structure will be used for multiple hash computations; each time a new hash
268 is computed, init_hash() will be called, followed by one or more calls to
269 update_hash(), and finally a call to finish_hash() to produce the resulting hash.
270 
271 The intention is that you will create a structure that includes uECC_HashContext
272 followed by any hash-specific data. For example:
273 
274 typedef struct SHA256_HashContext {
275  uECC_HashContext uECC;
276  SHA256_CTX ctx;
277 } SHA256_HashContext;
278 
279 void init_SHA256(uECC_HashContext *base) {
280  SHA256_HashContext *context = (SHA256_HashContext *)base;
281  SHA256_Init(&context->ctx);
282 }
283 
284 void update_SHA256(uECC_HashContext *base,
285  const uint8_t *message,
286  unsigned message_size) {
287  SHA256_HashContext *context = (SHA256_HashContext *)base;
288  SHA256_Update(&context->ctx, message, message_size);
289 }
290 
291 void finish_SHA256(uECC_HashContext *base, uint8_t *hash_result) {
292  SHA256_HashContext *context = (SHA256_HashContext *)base;
293  SHA256_Final(hash_result, &context->ctx);
294 }
295 
296 ... when signing ...
297 {
298  uint8_t tmp[32 + 32 + 64];
299  SHA256_HashContext ctx = {{&init_SHA256, &update_SHA256, &finish_SHA256, 64, 32, tmp}};
300  uECC_sign_deterministic(key, message_hash, &ctx.uECC, signature);
301 }
302 */
303 typedef struct uECC_HashContext {
304  void (*init_hash)(const struct uECC_HashContext *context);
305  void (*update_hash)(const struct uECC_HashContext *context,
306  const uint8_t *message,
307  unsigned message_size);
308  void (*finish_hash)(const struct uECC_HashContext *context, uint8_t *hash_result);
309  unsigned block_size; /* Hash function block size in bytes, eg 64 for SHA-256. */
310  unsigned result_size; /* Hash function result size in bytes, eg 32 for SHA-256. */
311  uint8_t *tmp; /* Must point to a buffer of at least (2 * result_size + block_size) bytes. */
313 
314 /* uECC_sign_deterministic() function.
315 Generate an ECDSA signature for a given hash value, using a deterministic algorithm
316 (see RFC 6979). You do not need to set the RNG using uECC_set_rng() before calling
317 this function; however, if the RNG is defined it will improve resistance to side-channel
318 attacks.
319 
320 Usage: Compute a hash of the data you wish to sign (SHA-2 is recommended) and pass it to
321 this function along with your private key and a hash context. Note that the message_hash
322 does not need to be computed with the same hash function used by hash_context.
323 
324 Inputs:
325  private_key - Your private key.
326  message_hash - The hash of the message to sign.
327  hash_size - The size of message_hash in bytes.
328  hash_context - A hash context to use.
329 
330 Outputs:
331  signature - Will be filled in with the signature value.
332 
333 Returns 1 if the signature generated successfully, 0 if an error occurred.
334 */
335 int uECC_sign_deterministic(const uint8_t *private_key,
336  const uint8_t *message_hash,
337  unsigned hash_size,
338  const uECC_HashContext *hash_context,
339  uint8_t *signature,
340  uECC_Curve curve);
341 
342 /* uECC_verify() function.
343 Verify an ECDSA signature.
344 
345 Usage: Compute the hash of the signed data using the same hash as the signer and
346 pass it to this function along with the signer's public key and the signature values (r and s).
347 
348 Inputs:
349  public_key - The signer's public key.
350  message_hash - The hash of the signed data.
351  hash_size - The size of message_hash in bytes.
352  signature - The signature value.
353 
354 Returns 1 if the signature is valid, 0 if it is invalid.
355 */
356 int uECC_verify(const uint8_t *public_key,
357  const uint8_t *message_hash,
358  unsigned hash_size,
359  const uint8_t *signature,
360  uECC_Curve curve);
361 
362 #ifdef __cplusplus
363 } /* end of extern "C" */
364 #endif
365 
366 #endif /* _UECC_H_ */
uECC_Curve uECC_secp256k1(void)
unsigned result_size
Definition: uECC.h:310
uint8_t * tmp
Definition: uECC.h:311
int uECC_sign_deterministic(const uint8_t *private_key, const uint8_t *message_hash, unsigned hash_size, const uECC_HashContext *hash_context, uint8_t *signature, uECC_Curve curve)
Definition: uECC.c:1378
uECC_Curve uECC_secp160r1(void)
void(* update_hash)(const struct uECC_HashContext *context, const uint8_t *message, unsigned message_size)
Definition: uECC.h:305
Definition: uECC.c:140
uECC_Curve uECC_secp224r1(void)
void(* finish_hash)(const struct uECC_HashContext *context, uint8_t *hash_result)
Definition: uECC.h:308
void uECC_compress(const uint8_t *public_key, uint8_t *compressed, uECC_Curve curve)
Definition: uECC.c:1081
struct uECC_HashContext uECC_HashContext
unsigned block_size
Definition: uECC.h:309
int uECC_valid_public_key(const uint8_t *public_key, uECC_Curve curve)
Definition: uECC.c:1142
int uECC_compute_public_key(const uint8_t *private_key, uint8_t *public_key, uECC_Curve curve)
Definition: uECC.c:1157
void uECC_decompress(const uint8_t *compressed, uint8_t *public_key, uECC_Curve curve)
Definition: uECC.c:1093
int uECC_curve_public_key_size(uECC_Curve curve)
Definition: uECC.c:203
int uECC_curve_private_key_size(uECC_Curve curve)
Definition: uECC.c:199
int uECC_make_key(uint8_t *public_key, uint8_t *private_key, uECC_Curve curve)
Definition: uECC.c:1005
const struct uECC_Curve_t * uECC_Curve
Definition: uECC.h:80
uECC_Curve uECC_secp256r1(void)
uECC_Curve uECC_secp192r1(void)
uECC_RNG_Function uECC_get_rng(void)
Definition: uECC.c:195
int uECC_verify(const uint8_t *public_key, const uint8_t *message_hash, unsigned hash_size, const uint8_t *signature, uECC_Curve curve)
Definition: uECC.c:1455
void(* init_hash)(const struct uECC_HashContext *context)
Definition: uECC.h:304
int uECC_sign(const uint8_t *private_key, const uint8_t *message_hash, unsigned hash_size, uint8_t *signature, uECC_Curve curve)
Definition: uECC.c:1307
Definition: uECC.h:303
int uECC_shared_secret(const uint8_t *public_key, const uint8_t *private_key, uint8_t *secret, uECC_Curve curve)
Definition: uECC.c:1035
void uECC_set_rng(uECC_RNG_Function rng_function)
Definition: uECC.c:191
int(* uECC_RNG_Function)(uint8_t *dest, unsigned size)
Definition: uECC.h:119