sara matheu
/
CurvasElipticas
Operaciones de generacion de claves, D-H, firma y validacion.
ecc.h@5:4f619b9a7bb2, 2015-02-20 (annotated)
- Committer:
- saranieves92
- Date:
- Fri Feb 20 18:37:50 2015 +0000
- Revision:
- 5:4f619b9a7bb2
- Parent:
- 3:74a69ff114ba
intento de rsa
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
saranieves92 | 0:beb846dbccf2 | 1 | #ifndef _MICRO_ECC_H_ |
saranieves92 | 0:beb846dbccf2 | 2 | #define _MICRO_ECC_H_ |
saranieves92 | 0:beb846dbccf2 | 3 | |
saranieves92 | 0:beb846dbccf2 | 4 | #include <stdint.h> |
saranieves92 | 0:beb846dbccf2 | 5 | |
saranieves92 | 0:beb846dbccf2 | 6 | /* Optimization settings. Define as 1 to enable an optimization, 0 to disable it. |
saranieves92 | 0:beb846dbccf2 | 7 | ECC_SQUARE_FUNC - If enabled, this will cause a specific function to be used for (scalar) squaring instead of the generic |
saranieves92 | 0:beb846dbccf2 | 8 | multiplication function. Improves speed by about 8% . |
saranieves92 | 0:beb846dbccf2 | 9 | */ |
saranieves92 | 0:beb846dbccf2 | 10 | #define ECC_SQUARE_FUNC 1 |
saranieves92 | 0:beb846dbccf2 | 11 | |
saranieves92 | 0:beb846dbccf2 | 12 | /* Inline assembly options. |
saranieves92 | 0:beb846dbccf2 | 13 | Inline assembly (gcc format) is provided for selected operations for Thumb and Thumb2/ARM. |
saranieves92 | 0:beb846dbccf2 | 14 | Improves speed by about 57% on Cortex-M0 when using ecc_asm_thumb. |
saranieves92 | 0:beb846dbccf2 | 15 | |
saranieves92 | 0:beb846dbccf2 | 16 | Note: You must choose the appropriate option for your target architecture, or compilation will fail |
saranieves92 | 0:beb846dbccf2 | 17 | with strange assembler messages. |
saranieves92 | 0:beb846dbccf2 | 18 | */ |
saranieves92 | 0:beb846dbccf2 | 19 | #define ecc_asm_none 0 |
saranieves92 | 0:beb846dbccf2 | 20 | #define ecc_asm_thumb 1 /* ARM Thumb assembly (including Cortex-M0) */ |
saranieves92 | 0:beb846dbccf2 | 21 | #define ecc_asm_thumb2 2 /* ARM Thumb-2 assembly (eg Cortex-M3) */ |
saranieves92 | 0:beb846dbccf2 | 22 | #define ecc_asm_arm 3 /* Regular ARM assembly */ |
saranieves92 | 0:beb846dbccf2 | 23 | #ifndef ECC_ASM |
saranieves92 | 3:74a69ff114ba | 24 | #define ECC_ASM ecc_asm_1 |
saranieves92 | 0:beb846dbccf2 | 25 | #endif |
saranieves92 | 0:beb846dbccf2 | 26 | |
saranieves92 | 0:beb846dbccf2 | 27 | #define ECC_CONCAT1(a, b) a##b |
saranieves92 | 0:beb846dbccf2 | 28 | #define ECC_CONCAT(a, b) ECC_CONCAT1(a, b) |
saranieves92 | 0:beb846dbccf2 | 29 | |
saranieves92 | 0:beb846dbccf2 | 30 | /* Curve selection options. */ |
saranieves92 | 0:beb846dbccf2 | 31 | #define secp128r1 1 |
saranieves92 | 0:beb846dbccf2 | 32 | #define secp192r1 2 |
saranieves92 | 0:beb846dbccf2 | 33 | #define secp256r1 3 |
saranieves92 | 0:beb846dbccf2 | 34 | #define secp384r1 4 |
saranieves92 | 0:beb846dbccf2 | 35 | #define secp256k1 5 |
saranieves92 | 0:beb846dbccf2 | 36 | |
saranieves92 | 0:beb846dbccf2 | 37 | #ifndef ECC_CURVE |
saranieves92 | 0:beb846dbccf2 | 38 | #define ECC_CURVE secp256r1 |
saranieves92 | 0:beb846dbccf2 | 39 | #endif |
saranieves92 | 0:beb846dbccf2 | 40 | |
saranieves92 | 0:beb846dbccf2 | 41 | #define ecc_size_1 4 |
saranieves92 | 0:beb846dbccf2 | 42 | #define ecc_size_2 6 |
saranieves92 | 0:beb846dbccf2 | 43 | #define ecc_size_3 8 |
saranieves92 | 0:beb846dbccf2 | 44 | #define ecc_size_4 12 |
saranieves92 | 0:beb846dbccf2 | 45 | #define ecc_size_5 8 |
saranieves92 | 0:beb846dbccf2 | 46 | |
saranieves92 | 0:beb846dbccf2 | 47 | #define NUM_ECC_DIGITS ECC_CONCAT(ecc_size_, ECC_CURVE) |
saranieves92 | 0:beb846dbccf2 | 48 | |
saranieves92 | 0:beb846dbccf2 | 49 | #ifdef __cplusplus |
saranieves92 | 0:beb846dbccf2 | 50 | extern "C" { |
saranieves92 | 0:beb846dbccf2 | 51 | #endif |
saranieves92 | 0:beb846dbccf2 | 52 | |
saranieves92 | 0:beb846dbccf2 | 53 | typedef struct EccPoint |
saranieves92 | 0:beb846dbccf2 | 54 | { |
saranieves92 | 3:74a69ff114ba | 55 | uint32_t x[NUM_ECC_DIGITS]; // es un array de 8 digitos (cada posicion es un numero de 32 bits) luego representa 256 bits |
saranieves92 | 0:beb846dbccf2 | 56 | uint32_t y[NUM_ECC_DIGITS]; |
saranieves92 | 0:beb846dbccf2 | 57 | } EccPoint; |
saranieves92 | 0:beb846dbccf2 | 58 | |
saranieves92 | 0:beb846dbccf2 | 59 | /* ecc_make_key() function. |
saranieves92 | 0:beb846dbccf2 | 60 | Create a public/private key pair. |
saranieves92 | 0:beb846dbccf2 | 61 | |
saranieves92 | 0:beb846dbccf2 | 62 | You must use a new nonpredictable random number to generate each new key pair. |
saranieves92 | 0:beb846dbccf2 | 63 | |
saranieves92 | 0:beb846dbccf2 | 64 | Outputs: |
saranieves92 | 0:beb846dbccf2 | 65 | p_publicKey - Will be filled in with the point representing the public key. |
saranieves92 | 0:beb846dbccf2 | 66 | p_privateKey - Will be filled in with the private key. |
saranieves92 | 0:beb846dbccf2 | 67 | |
saranieves92 | 0:beb846dbccf2 | 68 | Inputs: |
saranieves92 | 0:beb846dbccf2 | 69 | p_random - The random number to use to generate the key pair. |
saranieves92 | 0:beb846dbccf2 | 70 | |
saranieves92 | 0:beb846dbccf2 | 71 | Returns 1 if the key pair was generated successfully, 0 if an error occurred. If 0 is returned, |
saranieves92 | 0:beb846dbccf2 | 72 | try again with a different random number. |
saranieves92 | 0:beb846dbccf2 | 73 | */ |
saranieves92 | 0:beb846dbccf2 | 74 | int ecc_make_key(EccPoint *p_publicKey, uint32_t p_privateKey[NUM_ECC_DIGITS], |
saranieves92 | 0:beb846dbccf2 | 75 | const uint32_t p_random[NUM_ECC_DIGITS]); |
saranieves92 | 0:beb846dbccf2 | 76 | |
saranieves92 | 0:beb846dbccf2 | 77 | /* ecc_valid_public_key() function. |
saranieves92 | 0:beb846dbccf2 | 78 | Determine whether or not a given point is on the chosen elliptic curve (ie, is a valid public key). |
saranieves92 | 0:beb846dbccf2 | 79 | |
saranieves92 | 0:beb846dbccf2 | 80 | Inputs: |
saranieves92 | 0:beb846dbccf2 | 81 | p_publicKey - The point to check. |
saranieves92 | 0:beb846dbccf2 | 82 | |
saranieves92 | 0:beb846dbccf2 | 83 | Returns 1 if the given point is valid, 0 if it is invalid. |
saranieves92 | 0:beb846dbccf2 | 84 | */ |
saranieves92 | 0:beb846dbccf2 | 85 | int ecc_valid_public_key(const EccPoint *p_publicKey); |
saranieves92 | 0:beb846dbccf2 | 86 | |
saranieves92 | 0:beb846dbccf2 | 87 | /* ecdh_shared_secret() function. |
saranieves92 | 0:beb846dbccf2 | 88 | Compute a shared secret given your secret key and someone else's public key. |
saranieves92 | 0:beb846dbccf2 | 89 | |
saranieves92 | 0:beb846dbccf2 | 90 | Optionally, you can provide a random multiplier for resistance to DPA attacks. The random multiplier |
saranieves92 | 0:beb846dbccf2 | 91 | should probably be different for each invocation of ecdh_shared_secret(). |
saranieves92 | 0:beb846dbccf2 | 92 | |
saranieves92 | 0:beb846dbccf2 | 93 | Outputs: |
saranieves92 | 0:beb846dbccf2 | 94 | p_secret - Will be filled in with the shared secret value. |
saranieves92 | 0:beb846dbccf2 | 95 | |
saranieves92 | 0:beb846dbccf2 | 96 | Inputs: |
saranieves92 | 0:beb846dbccf2 | 97 | p_publicKey - The public key of the remote party. |
saranieves92 | 0:beb846dbccf2 | 98 | p_privateKey - Your private key. |
saranieves92 | 0:beb846dbccf2 | 99 | p_random - An optional random number to resist DPA attacks. Pass in NULL if DPA attacks are not a concern. |
saranieves92 | 0:beb846dbccf2 | 100 | |
saranieves92 | 0:beb846dbccf2 | 101 | Returns 1 if the shared secret was computed successfully, 0 otherwise. |
saranieves92 | 0:beb846dbccf2 | 102 | |
saranieves92 | 0:beb846dbccf2 | 103 | Note: It is recommended that you hash the result of ecdh_shared_secret before using it for symmetric encryption or HMAC. |
saranieves92 | 0:beb846dbccf2 | 104 | If you do not hash the shared secret, you must call ecc_valid_public_key() to verify that the remote side's public key is valid. |
saranieves92 | 0:beb846dbccf2 | 105 | If this is not done, an attacker could create a public key that would cause your use of the shared secret to leak information |
saranieves92 | 0:beb846dbccf2 | 106 | about your private key. */ |
saranieves92 | 0:beb846dbccf2 | 107 | int ecdh_shared_secret(uint32_t p_secret[NUM_ECC_DIGITS], const EccPoint *p_publicKey, |
saranieves92 | 0:beb846dbccf2 | 108 | const uint32_t p_privateKey[NUM_ECC_DIGITS], const uint32_t p_random[NUM_ECC_DIGITS]); |
saranieves92 | 0:beb846dbccf2 | 109 | |
saranieves92 | 0:beb846dbccf2 | 110 | /* ecdsa_sign() function. |
saranieves92 | 0:beb846dbccf2 | 111 | Generate an ECDSA signature for a given hash value. |
saranieves92 | 0:beb846dbccf2 | 112 | |
saranieves92 | 0:beb846dbccf2 | 113 | Usage: Compute a hash of the data you wish to sign (SHA-2 is recommended) and pass it in to |
saranieves92 | 0:beb846dbccf2 | 114 | this function along with your private key and a random number. |
saranieves92 | 0:beb846dbccf2 | 115 | You must use a new nonpredictable random number to generate each new signature. |
saranieves92 | 0:beb846dbccf2 | 116 | |
saranieves92 | 0:beb846dbccf2 | 117 | Outputs: |
saranieves92 | 0:beb846dbccf2 | 118 | r, s - Will be filled in with the signature values. |
saranieves92 | 0:beb846dbccf2 | 119 | |
saranieves92 | 0:beb846dbccf2 | 120 | Inputs: |
saranieves92 | 0:beb846dbccf2 | 121 | p_privateKey - Your private key. |
saranieves92 | 0:beb846dbccf2 | 122 | p_random - The random number to use to generate the signature. |
saranieves92 | 0:beb846dbccf2 | 123 | p_hash - The message hash to sign. |
saranieves92 | 0:beb846dbccf2 | 124 | |
saranieves92 | 0:beb846dbccf2 | 125 | Returns 1 if the signature generated successfully, 0 if an error occurred. If 0 is returned, |
saranieves92 | 0:beb846dbccf2 | 126 | try again with a different random number. |
saranieves92 | 0:beb846dbccf2 | 127 | */ |
saranieves92 | 0:beb846dbccf2 | 128 | int ecdsa_sign(uint32_t r[NUM_ECC_DIGITS], uint32_t s[NUM_ECC_DIGITS], |
saranieves92 | 0:beb846dbccf2 | 129 | const uint32_t p_privateKey[NUM_ECC_DIGITS], const uint32_t p_random[NUM_ECC_DIGITS], |
saranieves92 | 0:beb846dbccf2 | 130 | const uint32_t p_hash[NUM_ECC_DIGITS]); |
saranieves92 | 0:beb846dbccf2 | 131 | |
saranieves92 | 0:beb846dbccf2 | 132 | /* ecdsa_verify() function. |
saranieves92 | 0:beb846dbccf2 | 133 | Verify an ECDSA signature. |
saranieves92 | 0:beb846dbccf2 | 134 | |
saranieves92 | 0:beb846dbccf2 | 135 | Usage: Compute the hash of the signed data using the same hash as the signer and |
saranieves92 | 0:beb846dbccf2 | 136 | pass it to this function along with the signer's public key and the signature values (r and s). |
saranieves92 | 0:beb846dbccf2 | 137 | |
saranieves92 | 0:beb846dbccf2 | 138 | Inputs: |
saranieves92 | 0:beb846dbccf2 | 139 | p_publicKey - The signer's public key |
saranieves92 | 0:beb846dbccf2 | 140 | p_hash - The hash of the signed data. |
saranieves92 | 0:beb846dbccf2 | 141 | r, s - The signature values. |
saranieves92 | 0:beb846dbccf2 | 142 | |
saranieves92 | 0:beb846dbccf2 | 143 | Returns 1 if the signature is valid, 0 if it is invalid. |
saranieves92 | 0:beb846dbccf2 | 144 | */ |
saranieves92 | 0:beb846dbccf2 | 145 | int ecdsa_verify(const EccPoint *p_publicKey, const uint32_t p_hash[NUM_ECC_DIGITS], |
saranieves92 | 0:beb846dbccf2 | 146 | const uint32_t r[NUM_ECC_DIGITS], const uint32_t s[NUM_ECC_DIGITS]); |
saranieves92 | 0:beb846dbccf2 | 147 | |
saranieves92 | 0:beb846dbccf2 | 148 | /* ecc_bytes2native() function. |
saranieves92 | 0:beb846dbccf2 | 149 | Convert an integer in standard octet representation to the native format. |
saranieves92 | 0:beb846dbccf2 | 150 | |
saranieves92 | 0:beb846dbccf2 | 151 | Outputs: |
saranieves92 | 0:beb846dbccf2 | 152 | p_native - Will be filled in with the native integer value. |
saranieves92 | 0:beb846dbccf2 | 153 | |
saranieves92 | 0:beb846dbccf2 | 154 | Inputs: |
saranieves92 | 0:beb846dbccf2 | 155 | p_bytes - The standard octet representation of the integer to convert. |
saranieves92 | 0:beb846dbccf2 | 156 | */ |
saranieves92 | 0:beb846dbccf2 | 157 | void ecc_bytes2native(uint32_t p_native[NUM_ECC_DIGITS], const uint8_t p_bytes[NUM_ECC_DIGITS*4]); |
saranieves92 | 0:beb846dbccf2 | 158 | |
saranieves92 | 0:beb846dbccf2 | 159 | /* ecc_native2bytes() function. |
saranieves92 | 0:beb846dbccf2 | 160 | Convert an integer in native format to the standard octet representation. |
saranieves92 | 0:beb846dbccf2 | 161 | |
saranieves92 | 0:beb846dbccf2 | 162 | Outputs: |
saranieves92 | 0:beb846dbccf2 | 163 | p_bytes - Will be filled in with the standard octet representation of the integer. |
saranieves92 | 0:beb846dbccf2 | 164 | |
saranieves92 | 0:beb846dbccf2 | 165 | Inputs: |
saranieves92 | 0:beb846dbccf2 | 166 | p_native - The native integer value to convert. |
saranieves92 | 0:beb846dbccf2 | 167 | */ |
saranieves92 | 0:beb846dbccf2 | 168 | void ecc_native2bytes(uint8_t p_bytes[NUM_ECC_DIGITS*4], const uint32_t p_native[NUM_ECC_DIGITS]); |
saranieves92 | 0:beb846dbccf2 | 169 | |
saranieves92 | 0:beb846dbccf2 | 170 | /* ecc_point_compress() function. |
saranieves92 | 0:beb846dbccf2 | 171 | Compress a point from native format into the standard compressed octet representation. |
saranieves92 | 0:beb846dbccf2 | 172 | |
saranieves92 | 0:beb846dbccf2 | 173 | Outputs: |
saranieves92 | 0:beb846dbccf2 | 174 | p_compressed - Will be filled in with the compressed point representation. |
saranieves92 | 0:beb846dbccf2 | 175 | |
saranieves92 | 0:beb846dbccf2 | 176 | Inputs: |
saranieves92 | 0:beb846dbccf2 | 177 | p_point - The point to compress. |
saranieves92 | 0:beb846dbccf2 | 178 | */ |
saranieves92 | 0:beb846dbccf2 | 179 | void ecc_point_compress(uint8_t p_compressed[NUM_ECC_DIGITS*4 + 1], const EccPoint *p_point); |
saranieves92 | 0:beb846dbccf2 | 180 | |
saranieves92 | 0:beb846dbccf2 | 181 | /* ecc_point_decompress() function. |
saranieves92 | 0:beb846dbccf2 | 182 | Decompress a point from the standard compressed octet representation to native format. |
saranieves92 | 0:beb846dbccf2 | 183 | |
saranieves92 | 0:beb846dbccf2 | 184 | Outputs: |
saranieves92 | 0:beb846dbccf2 | 185 | p_point - Will be filled in with the native point representation. |
saranieves92 | 0:beb846dbccf2 | 186 | |
saranieves92 | 0:beb846dbccf2 | 187 | Inputs: |
saranieves92 | 0:beb846dbccf2 | 188 | p_compressed - The standard compressed octet representation of the point. |
saranieves92 | 0:beb846dbccf2 | 189 | */ |
saranieves92 | 0:beb846dbccf2 | 190 | void ecc_point_decompress(EccPoint *p_point, const uint8_t p_compressed[NUM_ECC_DIGITS*4 + 1]); |
saranieves92 | 0:beb846dbccf2 | 191 | |
saranieves92 | 0:beb846dbccf2 | 192 | #ifdef __cplusplus |
saranieves92 | 0:beb846dbccf2 | 193 | } // extern "C" |
saranieves92 | 0:beb846dbccf2 | 194 | #endif |
saranieves92 | 0:beb846dbccf2 | 195 | |
saranieves92 | 0:beb846dbccf2 | 196 | #endif /* _MICRO_ECC_H_ */ |