micro-ECC for mbed, ported from GCC version from Github,

Dependents:   mbed_microECC Wallet_v1

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers uECC.h Source File

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_ */