mirror of
https://github.com/kmackay/micro-ecc.git
synced 2026-07-26 13:29:05 +00:00
Renamed files, added more function documentation comments, did new performance testing.
This commit is contained in:
+20
-57
@@ -1,65 +1,28 @@
|
||||
LPC1114 at 48MHz (ARM Cortex-M0, 32-cycle 32x32 bit multiply)
|
||||
128 bits
|
||||
All off: avg time = 169 ms
|
||||
size = 1962 (including aeabi_lmul)
|
||||
|
||||
ECC_SOFT_MULT64 enabled: avg time = 164 ms
|
||||
size = 1942 (does not include aeabi_lmul)
|
||||
|
||||
ECC_USE_NAF enabled: avg time = 147 ms
|
||||
size = 2258
|
||||
|
||||
ECC_SQUARE_FUNC enabled: avg time = 137 ms
|
||||
size = 2538
|
||||
|
||||
160 bits
|
||||
All off: avg time = 269 ms
|
||||
size = 1864 (including aeabi_lmul)
|
||||
|
||||
ECC_SOFT_MULT64 enabled: avg time = 255 ms
|
||||
size = 1842 (does not include aeabi_lmul)
|
||||
|
||||
ECC_USE_NAF enabled: avg time = 224 ms
|
||||
size = 2158
|
||||
|
||||
ECC_SQUARE_FUNC enabled: avg time = 205 ms
|
||||
size = 2434
|
||||
asm on (#define ECC_ASM ecc_asm_thumb) (no lmul required)
|
||||
ECC_SQUARE_FUNC + ECC_USE_NAF: 75.9 (size = 2316 + 16)
|
||||
no opt: 85.5 (size = 1892 + 16)
|
||||
|
||||
192 bits
|
||||
All off: avg time = 439 ms
|
||||
size = 1808 (including aeabi_lmul)
|
||||
asm off
|
||||
ECC_SQUARE_FUNC + ECC_USE_NAF: 337.2 (size = 2276 + 112 (lmul) + 24)
|
||||
ECC_SQUARE_FUNC only: 393.0 (size = 2016 + 112 (lmul) + 24)
|
||||
ECC_USE_NAF only: 369.5 (size = 2072 + 112 (lmul) + 24)
|
||||
no opt: 431.9 (size = 1812 + 112 (lmul) + 24)
|
||||
|
||||
ECC_SOFT_MULT64 enabled: avg time = 414 ms
|
||||
size = 1786 (does not include aeabi_lmul)
|
||||
|
||||
ECC_USE_NAF enabled: avg time = 364 ms
|
||||
size = 2102
|
||||
|
||||
ECC_SQUARE_FUNC enabled: avg time = 325 ms
|
||||
size = 2378
|
||||
|
||||
224 bits
|
||||
All off: avg time = 674 ms
|
||||
size = 1866 (including aeabi_lmul)
|
||||
|
||||
ECC_SOFT_MULT64 enabled: avg time = 649 ms
|
||||
size = 1842 (does not include aeabi_lmul)
|
||||
|
||||
ECC_USE_NAF enabled: avg time = 571 ms
|
||||
size = 2158
|
||||
|
||||
ECC_SQUARE_FUNC enabled: avg time = 500 ms
|
||||
size = 2438
|
||||
asm on (#define ECC_ASM ecc_asm_thumb) (no lmul required)
|
||||
ECC_SQUARE_FUNC + ECC_USE_NAF: 147.7 (size = 2156 + 24)
|
||||
ECC_SQUARE_FUNC only: 172.6 (size = 1896 + 24)
|
||||
ECC_USE_NAF only: 158.2 (size = 2008 + 24)
|
||||
no opt: 183.9 (size = 1748 + 24)
|
||||
|
||||
256 bits
|
||||
All off: avg time = 1092 ms
|
||||
size = 2128 (including aeabi_lmul)
|
||||
asm on (#define ECC_ASM ecc_asm_thumb) (no lmul required)
|
||||
ECC_SQUARE_FUNC + ECC_USE_NAF: 385.8 (size = 2484 + 32)
|
||||
no opt: 473.6 (size = 2072 + 32)
|
||||
|
||||
ECC_SOFT_MULT64 enabled: avg time = 1058 ms
|
||||
size = 2110 (does not include aeabi_lmul)
|
||||
|
||||
ECC_USE_NAF enabled: avg time = 916 ms
|
||||
size = 2426
|
||||
|
||||
ECC_SQUARE_FUNC enabled: avg time = 810 ms
|
||||
size = 2718
|
||||
384 bits
|
||||
asm on (#define ECC_ASM ecc_asm_thumb) (no lmul required)
|
||||
ECC_SQUARE_FUNC + ECC_USE_NAF: 1128.2 (size = 2196 + 48)
|
||||
no opt: 1405.8 (size = 1784 + 48)
|
||||
+3
-1
@@ -1,4 +1,4 @@
|
||||
#include "ecdh.h"
|
||||
|
||||
|
||||
#if TARGET_LPC11XX
|
||||
#include "peripherals/uart.h"
|
||||
@@ -20,6 +20,8 @@ uint64_t getTimeMs(void)
|
||||
|
||||
#endif
|
||||
|
||||
#include "ecc.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
void vli_print(uint32_t *p_vli)
|
||||
|
||||
+17
-17
@@ -1,4 +1,4 @@
|
||||
#include "ecdh.h"
|
||||
#include "ecc.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
@@ -1283,22 +1283,7 @@ static void EccPoint_mult(EccPoint *p_result, EccPoint *p_point, uint32_t *p_sca
|
||||
|
||||
#endif /* ECC_USE_NAF */
|
||||
|
||||
int ecdh_shared_secret(uint32_t p_secret[NUM_ECC_DIGITS], EccPoint *p_publicKey, uint32_t p_privateKey[NUM_ECC_DIGITS])
|
||||
{
|
||||
EccPoint l_product;
|
||||
|
||||
EccPoint_mult(&l_product, p_publicKey, p_privateKey);
|
||||
if(EccPoint_isZero(&l_product))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
vli_set(p_secret, l_product.x);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ecdh_make_key(EccPoint *p_publicKey, uint32_t p_privateKey[NUM_ECC_DIGITS], uint32_t p_random[NUM_ECC_DIGITS])
|
||||
int ecc_make_key(EccPoint *p_publicKey, uint32_t p_privateKey[NUM_ECC_DIGITS], uint32_t p_random[NUM_ECC_DIGITS])
|
||||
{
|
||||
/* Make sure the private key is in the range [1, n-1].
|
||||
For the supported curves, n is always large enough that we only need to subtract once at most. */
|
||||
@@ -1349,6 +1334,21 @@ int ecc_valid_public_key(EccPoint *p_publicKey)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ecdh_shared_secret(uint32_t p_secret[NUM_ECC_DIGITS], EccPoint *p_publicKey, uint32_t p_privateKey[NUM_ECC_DIGITS])
|
||||
{
|
||||
EccPoint l_product;
|
||||
|
||||
EccPoint_mult(&l_product, p_publicKey, p_privateKey);
|
||||
if(EccPoint_isZero(&l_product))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
vli_set(p_secret, l_product.x);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* -------- ECDSA code -------- */
|
||||
|
||||
/* Computes p_result = (p_left * p_right) % p_mod. */
|
||||
@@ -0,0 +1,132 @@
|
||||
#ifndef _MICRO_ECC_H_
|
||||
#define _MICRO_ECC_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* Optimization settings. Define as 1 to enable an optimization, 0 to disable it.
|
||||
ECC_SQUARE_FUNC - If enabled, this will cause a specific function to be used for (scalar) squaring instead of the generic
|
||||
multiplication function. Improves speed by about 8% .
|
||||
ECC_USE_NAF - If enabled, this will convert the private key to a non-adjacent form before point multiplication.
|
||||
Improves speed by about 14%.
|
||||
*/
|
||||
#define ECC_SQUARE_FUNC 1
|
||||
#define ECC_USE_NAF 1
|
||||
|
||||
/* Inline assembly options.
|
||||
Inline assembly (gcc format) is provided for selected operations for Thumb and Thumb2/ARM.
|
||||
Improves speed by about 57% on Cortex-M0.
|
||||
|
||||
Note: You must choose the appropriate option for your target architecture, or compilation will fail
|
||||
with strange assembler messages.
|
||||
*/
|
||||
#define ecc_asm_none 0
|
||||
#define ecc_asm_thumb 1 /* ARM Thumb assembly (including Cortex-M0) */
|
||||
#define ecc_asm_thumb2 2 /* ARM Thumb-2 assembly (eg Cortex-M3) */
|
||||
#define ecc_asm_arm 3 /* Regular ARM assembly */
|
||||
#ifndef ECC_ASM
|
||||
#define ECC_ASM ecc_asm_none
|
||||
#endif
|
||||
|
||||
/* Curve selection options. */
|
||||
#define secp128r1 4
|
||||
#define secp192r1 6
|
||||
#define secp256r1 8
|
||||
#define secp384r1 12
|
||||
#ifndef ECC_CURVE
|
||||
#define ECC_CURVE secp192r1
|
||||
#endif
|
||||
|
||||
#if (ECC_CURVE != secp128r1 && ECC_CURVE != secp192r1 && ECC_CURVE != secp256r1 && ECC_CURVE != secp384r1)
|
||||
#error "Must define ECC_CURVE to one of the available curves"
|
||||
#endif
|
||||
|
||||
#define NUM_ECC_DIGITS ECC_CURVE
|
||||
|
||||
typedef struct EccPoint
|
||||
{
|
||||
uint32_t x[NUM_ECC_DIGITS];
|
||||
uint32_t y[NUM_ECC_DIGITS];
|
||||
} EccPoint;
|
||||
|
||||
/* ecc_make_key() function.
|
||||
Create a public/private key pair.
|
||||
|
||||
You must use a new nonpredictable random number to generate each new key pair.
|
||||
|
||||
Outputs:
|
||||
p_publicKey - Will be filled in with the point representing the public key.
|
||||
p_privateKey - Will be filled in with the private key.
|
||||
|
||||
Inputs:
|
||||
p_random - The random number to use to generate the key pair.
|
||||
|
||||
Returns 1 if the key pair was generated successfully, 0 if an error occurred. If 0 is returned,
|
||||
try again with a different random number.
|
||||
*/
|
||||
int ecc_make_key(EccPoint *p_publicKey, uint32_t p_privateKey[NUM_ECC_DIGITS], uint32_t p_random[NUM_ECC_DIGITS]);
|
||||
|
||||
/* ecc_valid_public_key() function.
|
||||
Determine whether or not a given point is on the chosen elliptic curve (ie, is a valid public key).
|
||||
|
||||
Inputs:
|
||||
p_publicKey - The point to check.
|
||||
|
||||
Returns 1 if the given point is valid, 0 if it is invalid.
|
||||
*/
|
||||
int ecc_valid_public_key(EccPoint *p_publicKey);
|
||||
|
||||
/* ecdh_shared_secret() function.
|
||||
Compute a shared secret given your secret key and someone else's public key.
|
||||
|
||||
Outputs:
|
||||
p_secret - Will be filled in with the shared secret value.
|
||||
|
||||
Inputs:
|
||||
p_publicKey - The public key of the remote party.
|
||||
p_privateKey - Your private key.
|
||||
|
||||
Returns 1 if the shared secret was computed successfully, 0 otherwise.
|
||||
|
||||
Note: It is recommended that you hash the result of ecdh_shared_secret before using it for symmetric encryption or HMAC.
|
||||
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.
|
||||
If this is not done, an attacker could create a public key that would cause your use of the shared secret to leak information
|
||||
about your private key. */
|
||||
int ecdh_shared_secret(uint32_t p_secret[NUM_ECC_DIGITS], EccPoint *p_publicKey, uint32_t p_privateKey[NUM_ECC_DIGITS]);
|
||||
|
||||
/* ecdsa_sign() function.
|
||||
Generate an ECDSA signature for a given hash value.
|
||||
|
||||
Usage: Compute a hash of the data you wish to sign (SHA-2 is recommended) and pass it in to
|
||||
this function along with your private key and a random number.
|
||||
You must use a new nonpredictable random number to generate each new signature.
|
||||
|
||||
Outputs:
|
||||
r, s - Will be filled in with the signature values.
|
||||
|
||||
Inputs:
|
||||
p_privateKey - Your private key.
|
||||
p_random - The random number to use to generate the signature.
|
||||
p_hash - The message hash to sign.
|
||||
|
||||
Returns 1 if the signature generated successfully, 0 if an error occurred. If 0 is returned,
|
||||
try again with a different random number.
|
||||
*/
|
||||
int ecdsa_sign(uint32_t r[NUM_ECC_DIGITS], uint32_t s[NUM_ECC_DIGITS], uint32_t p_privateKey[NUM_ECC_DIGITS],
|
||||
uint32_t p_random[NUM_ECC_DIGITS], uint32_t p_hash[NUM_ECC_DIGITS]);
|
||||
|
||||
/* ecdsa_verify() function.
|
||||
Verify an ECDSA signature.
|
||||
|
||||
Usage: Compute the hash of the signed data using the same hash as the signer and
|
||||
pass it to this function along with the signer's public key and the signature values (r and s).
|
||||
|
||||
Inputs:
|
||||
p_publicKey - The signer's public key
|
||||
p_hash - The hash of the signed data.
|
||||
r, s - The signature values.
|
||||
|
||||
Returns 1 if the signature is valid, 0 if it is invalid.
|
||||
*/
|
||||
int ecdsa_verify(EccPoint *p_publicKey, uint32_t p_hash[NUM_ECC_DIGITS], uint32_t r[NUM_ECC_DIGITS], uint32_t s[NUM_ECC_DIGITS]);
|
||||
|
||||
#endif /* _MICRO_ECC_H_ */
|
||||
@@ -1,55 +0,0 @@
|
||||
#ifndef _MICRO_ECDH_H_
|
||||
#define _MICRO_ECDH_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* Optimization settings. Define as 1 to enable an optimization, 0 to disable it.
|
||||
ECC_SQUARE_FUNC - If enabled, this will cause a specific function to be used for (scalar) squaring instead of the generic
|
||||
multiplication function. Improves speed by about 8% .
|
||||
ECC_USE_NAF - If enabled, this will convert the private key to a non-adjacent form before point multiplication.
|
||||
Improves speed by about 10%.
|
||||
*/
|
||||
#define ECC_SQUARE_FUNC 1
|
||||
#define ECC_USE_NAF 1
|
||||
|
||||
#define ecc_asm_none 0
|
||||
#define ecc_asm_thumb 1 /* ARM Thumb assembly (including Cortex-M0) */
|
||||
#define ecc_asm_thumb2 2 /* ARM Thumb-2 assembly */
|
||||
#define ecc_asm_arm 3 /* Regular ARM assembly */
|
||||
#ifndef ECC_ASM
|
||||
#define ECC_ASM ecc_asm_none
|
||||
#endif
|
||||
|
||||
#define secp128r1 4
|
||||
#define secp192r1 6
|
||||
#define secp256r1 8
|
||||
#define secp384r1 12
|
||||
#ifndef ECC_CURVE
|
||||
#define ECC_CURVE secp192r1
|
||||
#endif
|
||||
|
||||
#if (ECC_CURVE != secp128r1 && ECC_CURVE != secp192r1 && ECC_CURVE != secp256r1 && ECC_CURVE != secp384r1)
|
||||
#error "Must define ECC_CURVE to one of the available curves"
|
||||
#endif
|
||||
|
||||
#define NUM_ECC_DIGITS ECC_CURVE
|
||||
|
||||
typedef struct EccPoint
|
||||
{
|
||||
uint32_t x[NUM_ECC_DIGITS];
|
||||
uint32_t y[NUM_ECC_DIGITS];
|
||||
} EccPoint;
|
||||
|
||||
/* Note: It is recommended that you hash the result of ecdh_shared_secret before using it for symmetric encryption or HMAC.
|
||||
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.
|
||||
If this is not done, an attacker could create a public key that would cause your use of the shared secret to leak information
|
||||
about your private key. */
|
||||
int ecdh_shared_secret(uint32_t p_secret[NUM_ECC_DIGITS], EccPoint *p_publicKey, uint32_t p_privateKey[NUM_ECC_DIGITS]);
|
||||
int ecdh_make_key(EccPoint *p_publicKey, uint32_t p_privateKey[NUM_ECC_DIGITS], uint32_t p_random[NUM_ECC_DIGITS]);
|
||||
int ecc_valid_public_key(EccPoint *p_publicKey);
|
||||
|
||||
int ecdsa_sign(uint32_t r[NUM_ECC_DIGITS], uint32_t s[NUM_ECC_DIGITS], uint32_t p_privateKey[NUM_ECC_DIGITS],
|
||||
uint32_t p_random[NUM_ECC_DIGITS], uint32_t p_hash[NUM_ECC_DIGITS]);
|
||||
int ecdsa_verify(EccPoint *p_publicKey, uint32_t p_hash[NUM_ECC_DIGITS], uint32_t r[NUM_ECC_DIGITS], uint32_t s[NUM_ECC_DIGITS]);
|
||||
|
||||
#endif /* _MICRO_ECDH_H_ */
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
#include "ecdh.h"
|
||||
#include "ecc.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@@ -54,7 +54,7 @@ int main()
|
||||
fflush(stdout);
|
||||
getRandomBytes((char *)l_private, NUM_ECC_DIGITS * sizeof(uint32_t));
|
||||
|
||||
ecdh_make_key(&l_public, l_private, l_private);
|
||||
ecc_make_key(&l_public, l_private, l_private);
|
||||
|
||||
getRandomBytes((char *)l_hash, NUM_ECC_DIGITS * sizeof(uint32_t));
|
||||
getRandomBytes((char *)l_random, NUM_ECC_DIGITS * sizeof(uint32_t));
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
#include "ecdh.h"
|
||||
#include "ecc.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@@ -51,7 +51,7 @@ int main(int argc, char **argv)
|
||||
for(i=0; i<l_num; ++i)
|
||||
{
|
||||
getRandomBytes((char *)l_private[i], NUM_ECC_DIGITS * sizeof(uint32_t));
|
||||
ecdh_make_key(&l_public[i], l_private[i], l_private[i]);
|
||||
ecc_make_key(&l_public[i], l_private[i], l_private[i]);
|
||||
}
|
||||
|
||||
printf("uint32_t l_private[%u][NUM_ECC_DIGITS] = {\n", l_num);
|
||||
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
#include "ecdh.h"
|
||||
#include "ecc.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@@ -54,8 +54,8 @@ int main()
|
||||
getRandomBytes((char *)l_secret1, NUM_ECC_DIGITS * sizeof(uint32_t));
|
||||
getRandomBytes((char *)l_secret2, NUM_ECC_DIGITS * sizeof(uint32_t));
|
||||
|
||||
ecdh_make_key(&l_Q1, l_secret1, l_secret1);
|
||||
ecdh_make_key(&l_Q2, l_secret2, l_secret2);
|
||||
ecc_make_key(&l_Q1, l_secret1, l_secret1);
|
||||
ecc_make_key(&l_Q2, l_secret2, l_secret2);
|
||||
|
||||
if(!ecdh_shared_secret(l_shared1, &l_Q1, l_secret2))
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user