mirror of
https://github.com/kmackay/micro-ecc.git
synced 2026-08-10 04:07:46 +00:00
Initial ECDSA implementation.
This commit is contained in:
@@ -16,7 +16,7 @@ ECC_SOFT_MULT64 - For platforms that do not have instructions to allow a fast 64
|
||||
#define ECC_USE_NAF 1
|
||||
#define ECC_SOFT_MULT64 1
|
||||
|
||||
#define ECC_CURVE secp128r1
|
||||
#define ECC_CURVE secp160r1
|
||||
|
||||
#define secp128r1 4
|
||||
#define secp160r1 5
|
||||
@@ -38,5 +38,15 @@ typedef struct EccPoint
|
||||
|
||||
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);
|
||||
|
||||
/* 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 ecdsa_sign(uint32_t p_privateKey[NUM_ECC_DIGITS], uint32_t p_random[NUM_ECC_DIGITS], uint32_t p_hash[NUM_ECC_DIGITS],
|
||||
uint32_t r[NUM_ECC_DIGITS], uint32_t s[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_ */
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
#include "ecdh.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
extern void EccPoint_mult(EccPoint *p_result, EccPoint *p_point, uint32_t *p_scalar);
|
||||
|
||||
void vli_print(uint32_t *p_vli, unsigned int p_size)
|
||||
{
|
||||
while(p_size)
|
||||
{
|
||||
printf("%08X ", (unsigned)p_vli[p_size - 1]);
|
||||
--p_size;
|
||||
}
|
||||
}
|
||||
|
||||
int randfd;
|
||||
|
||||
void getRandomBytes(void *p_dest, unsigned p_size)
|
||||
{
|
||||
if(read(randfd, p_dest, p_size) != (int)p_size)
|
||||
{
|
||||
printf("Failed to get random bytes.\n");
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
EccPoint l_public;
|
||||
uint32_t l_private[NUM_ECC_DIGITS];
|
||||
|
||||
uint32_t l_hash[NUM_ECC_DIGITS];
|
||||
uint32_t l_random[NUM_ECC_DIGITS];
|
||||
|
||||
uint32_t r[NUM_ECC_DIGITS];
|
||||
uint32_t s[NUM_ECC_DIGITS];
|
||||
|
||||
int i;
|
||||
|
||||
randfd = open("/dev/urandom", O_RDONLY);
|
||||
if(randfd == -1)
|
||||
{
|
||||
printf("No access to urandom\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("Testing 256 signatures\n");
|
||||
|
||||
for(i=0; i<256; ++i)
|
||||
{
|
||||
printf(".");
|
||||
fflush(stdout);
|
||||
getRandomBytes((char *)l_private, NUM_ECC_DIGITS * sizeof(uint32_t));
|
||||
|
||||
ecdh_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));
|
||||
|
||||
if(!ecdsa_sign(l_private, l_random, l_hash, r, s))
|
||||
{
|
||||
printf("ecdsa_sign() failed\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!ecc_valid_public_key(&l_public))
|
||||
{
|
||||
printf("Not a valid public key!\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!ecdsa_verify(&l_public, l_hash, r, s))
|
||||
{
|
||||
printf("ecdsa_verify() failed\n");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
#include "ecdh.h"
|
||||
|
||||
#if (ECC_CURVE == secp160r1)
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
void vli_print(uint32_t *p_vli, unsigned int p_size)
|
||||
{
|
||||
while(p_size)
|
||||
{
|
||||
printf("%08X ", (unsigned)p_vli[p_size - 1]);
|
||||
--p_size;
|
||||
}
|
||||
}
|
||||
|
||||
/* Test data from http://www.secg.org/collateral/gec2.pdf page 2
|
||||
Requires that ECC_CURVE be set to secp160r1. */
|
||||
|
||||
int main()
|
||||
{
|
||||
uint32_t l_privateKey[NUM_ECC_DIGITS] = {0xB2A4E982, 0x72CB6D57, 0xB0733079, 0x3CE144E6, 0xAA374FFC};
|
||||
EccPoint l_publicKey = {
|
||||
{0x51419DC0, 0x3C032062, 0x0E75A24A, 0xECC406ED, 0x51B4496F},
|
||||
{0x1756AA6C, 0x4F381CCC, 0x68D79389, 0x73A514B4, 0xC28DCB4B}
|
||||
};
|
||||
uint32_t l_random[NUM_ECC_DIGITS] = {0xdecd52da, 0x2ac5d528, 0xb9185c8b, 0x681a3f28, 0x7b012db7};
|
||||
uint32_t l_hash[NUM_ECC_DIGITS] = {0x9cd0d89d, 0x7850c26c, 0xba3e2571, 0x4706816a, 0xa9993e36};
|
||||
|
||||
uint32_t r[NUM_ECC_DIGITS];
|
||||
uint32_t s[NUM_ECC_DIGITS];
|
||||
|
||||
if(!ecdsa_sign(l_privateKey, l_random, l_hash, r, s))
|
||||
{
|
||||
printf("ecdsa_sign() failed\n");
|
||||
}
|
||||
|
||||
printf("r: ");
|
||||
vli_print(r, NUM_ECC_DIGITS);
|
||||
printf("\n");
|
||||
printf("s: ");
|
||||
vli_print(s, NUM_ECC_DIGITS);
|
||||
printf("\n");
|
||||
|
||||
if(!ecdsa_verify(&l_publicKey, l_hash, r, s))
|
||||
{
|
||||
printf("ecdsa_verify() failed\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user