micro-ECC for mbed, ported from GCC version from Github,
Dependents: mbed_microECC Wallet_v1
uECC.h
00001 /* Copyright 2014, Kenneth MacKay. Licensed under the BSD 2-clause license. */ 00002 00003 #ifndef _UECC_H_ 00004 #define _UECC_H_ 00005 00006 #include <stdint.h> 00007 00008 /* Platform selection options. 00009 If uECC_PLATFORM is not defined, the code will try to guess it based on compiler macros. 00010 Possible values for uECC_PLATFORM are defined below: */ 00011 #define uECC_arch_other 0 00012 #define uECC_x86 1 00013 #define uECC_x86_64 2 00014 #define uECC_arm 3 00015 #define uECC_arm_thumb 4 00016 #define uECC_arm_thumb2 5 00017 #define uECC_arm64 6 00018 #define uECC_avr 7 00019 00020 /* Defined arch to others to allow mbed compiler go through building first */ 00021 #define uECC_PLATFORM uECC_arch_other 00022 00023 /* If desired, you can define uECC_WORD_SIZE as appropriate for your platform (1, 4, or 8 bytes). 00024 If uECC_WORD_SIZE is not explicitly defined then it will be automatically set based on your 00025 platform. */ 00026 00027 /* Optimization level; trade speed for code size. 00028 Larger values produce code that is faster but larger. 00029 Currently supported values are 0 - 4; 0 is unusably slow for most applications. 00030 Optimization level 4 currently only has an effect ARM platforms where more than one 00031 curve is enabled. */ 00032 #ifndef uECC_OPTIMIZATION_LEVEL 00033 #define uECC_OPTIMIZATION_LEVEL 2 00034 #endif 00035 00036 /* uECC_SQUARE_FUNC - If enabled (defined as nonzero), this will cause a specific function to be 00037 used for (scalar) squaring instead of the generic multiplication function. This can make things 00038 faster somewhat faster, but increases the code size. */ 00039 #ifndef uECC_SQUARE_FUNC 00040 #define uECC_SQUARE_FUNC 0 00041 #endif 00042 00043 /* uECC_VLI_NATIVE_LITTLE_ENDIAN - If enabled (defined as nonzero), this will switch to native 00044 little-endian format for *all* arrays passed in and out of the public API. This includes public 00045 and private keys, shared secrets, signatures and message hashes. 00046 Using this switch reduces the amount of call stack memory used by uECC, since less intermediate 00047 translations are required. 00048 Note that this will *only* work on native little-endian processors and it will treat the uint8_t 00049 arrays passed into the public API as word arrays, therefore requiring the provided byte arrays 00050 to be word aligned on architectures that do not support unaligned accesses. 00051 IMPORTANT: Keys and signatures generated with uECC_VLI_NATIVE_LITTLE_ENDIAN=1 are incompatible 00052 with keys and signatures generated with uECC_VLI_NATIVE_LITTLE_ENDIAN=0; all parties must use 00053 the same endianness. */ 00054 #ifndef uECC_VLI_NATIVE_LITTLE_ENDIAN 00055 #define uECC_VLI_NATIVE_LITTLE_ENDIAN 0 00056 #endif 00057 00058 /* Curve support selection. Set to 0 to remove that curve. */ 00059 #ifndef uECC_SUPPORTS_secp160r1 00060 #define uECC_SUPPORTS_secp160r1 1 00061 #endif 00062 #ifndef uECC_SUPPORTS_secp192r1 00063 #define uECC_SUPPORTS_secp192r1 1 00064 #endif 00065 #ifndef uECC_SUPPORTS_secp224r1 00066 #define uECC_SUPPORTS_secp224r1 1 00067 #endif 00068 #ifndef uECC_SUPPORTS_secp256r1 00069 #define uECC_SUPPORTS_secp256r1 1 00070 #endif 00071 #ifndef uECC_SUPPORTS_secp256k1 00072 #define uECC_SUPPORTS_secp256k1 1 00073 #endif 00074 00075 /* Specifies whether compressed point format is supported. 00076 Set to 0 to disable point compression/decompression functions. */ 00077 #ifndef uECC_SUPPORT_COMPRESSED_POINT 00078 #define uECC_SUPPORT_COMPRESSED_POINT 1 00079 #endif 00080 00081 struct uECC_Curve_t; 00082 typedef const struct uECC_Curve_t * uECC_Curve; 00083 00084 #ifdef __cplusplus 00085 extern "C" 00086 { 00087 #endif 00088 00089 #if uECC_SUPPORTS_secp160r1 00090 uECC_Curve uECC_secp160r1(void); 00091 #endif 00092 #if uECC_SUPPORTS_secp192r1 00093 uECC_Curve uECC_secp192r1(void); 00094 #endif 00095 #if uECC_SUPPORTS_secp224r1 00096 uECC_Curve uECC_secp224r1(void); 00097 #endif 00098 #if uECC_SUPPORTS_secp256r1 00099 uECC_Curve uECC_secp256r1(void); 00100 #endif 00101 #if uECC_SUPPORTS_secp256k1 00102 uECC_Curve uECC_secp256k1(void); 00103 #endif 00104 00105 /* uECC_RNG_Function type 00106 The RNG function should fill 'size' random bytes into 'dest'. It should return 1 if 00107 'dest' was filled with random data, or 0 if the random data could not be generated. 00108 The filled-in values should be either truly random, or from a cryptographically-secure PRNG. 00109 00110 A correctly functioning RNG function must be set (using uECC_set_rng()) before calling 00111 uECC_make_key() or uECC_sign(). 00112 00113 Setting a correctly functioning RNG function improves the resistance to side-channel attacks 00114 for uECC_shared_secret() and uECC_sign_deterministic(). 00115 00116 A correct RNG function is set by default when building for Windows, Linux, or OS X. 00117 If you are building on another POSIX-compliant system that supports /dev/random or /dev/urandom, 00118 you can define uECC_POSIX to use the predefined RNG. For embedded platforms there is no predefined 00119 RNG function; you must provide your own. 00120 */ 00121 typedef int (*uECC_RNG_Function)(uint8_t *dest, unsigned size); 00122 00123 /* uECC_set_rng() function. 00124 Set the function that will be used to generate random bytes. The RNG function should 00125 return 1 if the random data was generated, or 0 if the random data could not be generated. 00126 00127 On platforms where there is no predefined RNG function (eg embedded platforms), this must 00128 be called before uECC_make_key() or uECC_sign() are used. 00129 00130 Inputs: 00131 rng_function - The function that will be used to generate random bytes. 00132 */ 00133 void uECC_set_rng(uECC_RNG_Function rng_function); 00134 00135 /* uECC_get_rng() function. 00136 00137 Returns the function that will be used to generate random bytes. 00138 */ 00139 uECC_RNG_Function uECC_get_rng(void); 00140 00141 /* uECC_curve_private_key_size() function. 00142 00143 Returns the size of a private key for the curve in bytes. 00144 */ 00145 int uECC_curve_private_key_size(uECC_Curve curve); 00146 00147 /* uECC_curve_public_key_size() function. 00148 00149 Returns the size of a public key for the curve in bytes. 00150 */ 00151 int uECC_curve_public_key_size(uECC_Curve curve); 00152 00153 /* uECC_make_key() function. 00154 Create a public/private key pair. 00155 00156 Outputs: 00157 public_key - Will be filled in with the public key. Must be at least 2 * the curve size 00158 (in bytes) long. For example, if the curve is secp256r1, public_key must be 64 00159 bytes long. 00160 private_key - Will be filled in with the private key. Must be as long as the curve order; this 00161 is typically the same as the curve size, except for secp160r1. For example, if the 00162 curve is secp256r1, private_key must be 32 bytes long. 00163 00164 For secp160r1, private_key must be 21 bytes long! Note that the first byte will 00165 almost always be 0 (there is about a 1 in 2^80 chance of it being non-zero). 00166 00167 Returns 1 if the key pair was generated successfully, 0 if an error occurred. 00168 */ 00169 int uECC_make_key(uint8_t *public_key, uint8_t *private_key, uECC_Curve curve); 00170 00171 /* uECC_shared_secret() function. 00172 Compute a shared secret given your secret key and someone else's public key. 00173 Note: It is recommended that you hash the result of uECC_shared_secret() before using it for 00174 symmetric encryption or HMAC. 00175 00176 Inputs: 00177 public_key - The public key of the remote party. 00178 private_key - Your private key. 00179 00180 Outputs: 00181 secret - Will be filled in with the shared secret value. Must be the same size as the 00182 curve size; for example, if the curve is secp256r1, secret must be 32 bytes long. 00183 00184 Returns 1 if the shared secret was generated successfully, 0 if an error occurred. 00185 */ 00186 int uECC_shared_secret(const uint8_t *public_key, 00187 const uint8_t *private_key, 00188 uint8_t *secret, 00189 uECC_Curve curve); 00190 00191 #if uECC_SUPPORT_COMPRESSED_POINT 00192 /* uECC_compress() function. 00193 Compress a public key. 00194 00195 Inputs: 00196 public_key - The public key to compress. 00197 00198 Outputs: 00199 compressed - Will be filled in with the compressed public key. Must be at least 00200 (curve size + 1) bytes long; for example, if the curve is secp256r1, 00201 compressed must be 33 bytes long. 00202 */ 00203 void uECC_compress(const uint8_t *public_key, uint8_t *compressed, uECC_Curve curve); 00204 00205 /* uECC_decompress() function. 00206 Decompress a compressed public key. 00207 00208 Inputs: 00209 compressed - The compressed public key. 00210 00211 Outputs: 00212 public_key - Will be filled in with the decompressed public key. 00213 */ 00214 void uECC_decompress(const uint8_t *compressed, uint8_t *public_key, uECC_Curve curve); 00215 #endif /* uECC_SUPPORT_COMPRESSED_POINT */ 00216 00217 /* uECC_valid_public_key() function. 00218 Check to see if a public key is valid. 00219 00220 Note that you are not required to check for a valid public key before using any other uECC 00221 functions. However, you may wish to avoid spending CPU time computing a shared secret or 00222 verifying a signature using an invalid public key. 00223 00224 Inputs: 00225 public_key - The public key to check. 00226 00227 Returns 1 if the public key is valid, 0 if it is invalid. 00228 */ 00229 int uECC_valid_public_key(const uint8_t *public_key, uECC_Curve curve); 00230 00231 /* uECC_compute_public_key() function. 00232 Compute the corresponding public key for a private key. 00233 00234 Inputs: 00235 private_key - The private key to compute the public key for 00236 00237 Outputs: 00238 public_key - Will be filled in with the corresponding public key 00239 00240 Returns 1 if the key was computed successfully, 0 if an error occurred. 00241 */ 00242 int uECC_compute_public_key(const uint8_t *private_key, uint8_t *public_key, uECC_Curve curve); 00243 00244 /* uECC_sign() function. 00245 Generate an ECDSA signature for a given hash value. 00246 00247 Usage: Compute a hash of the data you wish to sign (SHA-2 is recommended) and pass it in to 00248 this function along with your private key. 00249 00250 Inputs: 00251 private_key - Your private key. 00252 message_hash - The hash of the message to sign. 00253 hash_size - The size of message_hash in bytes. 00254 00255 Outputs: 00256 signature - Will be filled in with the signature value. Must be at least 2 * curve size long. 00257 For example, if the curve is secp256r1, signature must be 64 bytes long. 00258 00259 Returns 1 if the signature generated successfully, 0 if an error occurred. 00260 */ 00261 int uECC_sign(const uint8_t *private_key, 00262 const uint8_t *message_hash, 00263 unsigned hash_size, 00264 uint8_t *signature, 00265 uECC_Curve curve); 00266 00267 /* uECC_HashContext structure. 00268 This is used to pass in an arbitrary hash function to uECC_sign_deterministic(). 00269 The structure will be used for multiple hash computations; each time a new hash 00270 is computed, init_hash() will be called, followed by one or more calls to 00271 update_hash(), and finally a call to finish_hash() to produce the resulting hash. 00272 00273 The intention is that you will create a structure that includes uECC_HashContext 00274 followed by any hash-specific data. For example: 00275 00276 typedef struct SHA256_HashContext { 00277 uECC_HashContext uECC; 00278 SHA256_CTX ctx; 00279 } SHA256_HashContext; 00280 00281 void init_SHA256(uECC_HashContext *base) { 00282 SHA256_HashContext *context = (SHA256_HashContext *)base; 00283 SHA256_Init(&context->ctx); 00284 } 00285 00286 void update_SHA256(uECC_HashContext *base, 00287 const uint8_t *message, 00288 unsigned message_size) { 00289 SHA256_HashContext *context = (SHA256_HashContext *)base; 00290 SHA256_Update(&context->ctx, message, message_size); 00291 } 00292 00293 void finish_SHA256(uECC_HashContext *base, uint8_t *hash_result) { 00294 SHA256_HashContext *context = (SHA256_HashContext *)base; 00295 SHA256_Final(hash_result, &context->ctx); 00296 } 00297 00298 ... when signing ... 00299 { 00300 uint8_t tmp[32 + 32 + 64]; 00301 SHA256_HashContext ctx = {{&init_SHA256, &update_SHA256, &finish_SHA256, 64, 32, tmp}}; 00302 uECC_sign_deterministic(key, message_hash, &ctx.uECC, signature); 00303 } 00304 */ 00305 typedef struct uECC_HashContext { 00306 void (*init_hash)(const struct uECC_HashContext *context); 00307 void (*update_hash)(const struct uECC_HashContext *context, 00308 const uint8_t *message, 00309 unsigned message_size); 00310 void (*finish_hash)(const struct uECC_HashContext *context, uint8_t *hash_result); 00311 unsigned block_size; /* Hash function block size in bytes, eg 64 for SHA-256. */ 00312 unsigned result_size; /* Hash function result size in bytes, eg 32 for SHA-256. */ 00313 uint8_t *tmp; /* Must point to a buffer of at least (2 * result_size + block_size) bytes. */ 00314 } uECC_HashContext; 00315 00316 /* uECC_sign_deterministic() function. 00317 Generate an ECDSA signature for a given hash value, using a deterministic algorithm 00318 (see RFC 6979). You do not need to set the RNG using uECC_set_rng() before calling 00319 this function; however, if the RNG is defined it will improve resistance to side-channel 00320 attacks. 00321 00322 Usage: Compute a hash of the data you wish to sign (SHA-2 is recommended) and pass it to 00323 this function along with your private key and a hash context. Note that the message_hash 00324 does not need to be computed with the same hash function used by hash_context. 00325 00326 Inputs: 00327 private_key - Your private key. 00328 message_hash - The hash of the message to sign. 00329 hash_size - The size of message_hash in bytes. 00330 hash_context - A hash context to use. 00331 00332 Outputs: 00333 signature - Will be filled in with the signature value. 00334 00335 Returns 1 if the signature generated successfully, 0 if an error occurred. 00336 */ 00337 int uECC_sign_deterministic(const uint8_t *private_key, 00338 const uint8_t *message_hash, 00339 unsigned hash_size, 00340 const uECC_HashContext *hash_context, 00341 uint8_t *signature, 00342 uECC_Curve curve); 00343 00344 /* uECC_verify() function. 00345 Verify an ECDSA signature. 00346 00347 Usage: Compute the hash of the signed data using the same hash as the signer and 00348 pass it to this function along with the signer's public key and the signature values (r and s). 00349 00350 Inputs: 00351 public_key - The signer's public key. 00352 message_hash - The hash of the signed data. 00353 hash_size - The size of message_hash in bytes. 00354 signature - The signature value. 00355 00356 Returns 1 if the signature is valid, 0 if it is invalid. 00357 */ 00358 int uECC_verify(const uint8_t *public_key, 00359 const uint8_t *message_hash, 00360 unsigned hash_size, 00361 const uint8_t *signature, 00362 uECC_Curve curve); 00363 00364 #ifdef __cplusplus 00365 } /* end of extern "C" */ 00366 #endif 00367 00368 #endif /* _UECC_H_ */
Generated on Wed Jul 13 2022 03:48:20 by
1.7.2