Skip to content

Commit

Permalink
format of curve25519 key
Browse files Browse the repository at this point in the history
  • Loading branch information
JacobBarthelmeh committed Mar 5, 2015
1 parent 450ccea commit 7ef362d
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 63 deletions.
78 changes: 31 additions & 47 deletions wolfcrypt/src/ecc25519.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@
#include <wolfcrypt/src/misc.c>
#endif

#define MONTGOMERY_X_LE 65

const ecc25519_set_type ecc25519_sets[] = {
{
32,
Expand Down Expand Up @@ -102,7 +100,7 @@ int wc_ecc25519_make_key(RNG* rng, int keysize, ecc25519_key* key)
unsigned char n[ECC25519_KEYSIZE];
unsigned char p[ECC25519_KEYSIZE];
int i;
int err;
int ret;

if (key == NULL || rng == NULL)
return ECC_BAD_ARG_E;
Expand All @@ -112,17 +110,17 @@ int wc_ecc25519_make_key(RNG* rng, int keysize, ecc25519_key* key)
return ECC_BAD_ARG_E;

/* get random number from RNG */
err = wc_RNG_GenerateBlock(rng, n, keysize);
if (err != 0)
return err;
ret = wc_RNG_GenerateBlock(rng, n, keysize);
if (ret != 0)
return ret;

for (i = 0; i < keysize; ++i) key->k.point[i] = n[i];
key->k.point[ 0] &= 248;
key->k.point[31] &= 127;
key->k.point[31] |= 64;

/*compute public key*/
err = curve25519(p, key->k.point, basepoint);
ret = curve25519(p, key->k.point, basepoint);

/* store keys in big endian format */
for (i = 0; i < keysize; ++i) n[i] = key->k.point[i];
Expand All @@ -132,8 +130,9 @@ int wc_ecc25519_make_key(RNG* rng, int keysize, ecc25519_key* key)
}

ForceZero(n, keysize);
ForceZero(p, keysize);

return err;
return ret;
}


Expand All @@ -142,7 +141,8 @@ int wc_ecc25519_shared_secret(ecc25519_key* private_key, ecc25519_key* public_ke
{
unsigned char k[ECC25519_KEYSIZE];
unsigned char p[ECC25519_KEYSIZE];
int err = 0;
unsigned char o[ECC25519_KEYSIZE];
int ret = 0;
int i;

/* sanity check */
Expand All @@ -154,9 +154,6 @@ int wc_ecc25519_shared_secret(ecc25519_key* private_key, ecc25519_key* public_ke
if (public_key->p.point[0] > 0x7F)
return ECC_BAD_ARG_E;

if (*outlen < ECC25519_KEYSIZE)
return BUFFER_E;

XMEMSET(p, 0, sizeof(p));
XMEMSET(k, 0, sizeof(k));
XMEMSET(out, 0, ECC25519_KEYSIZE);
Expand All @@ -166,37 +163,35 @@ int wc_ecc25519_shared_secret(ecc25519_key* private_key, ecc25519_key* public_ke
k[i] = private_key->k.point[ECC25519_KEYSIZE - i - 1];
}

err = curve25519(out , k, p);
ret = curve25519(o , k, p);
*outlen = ECC25519_KEYSIZE;

for (i = 0; i < ECC25519_KEYSIZE; ++i) {
out[i] = o[ECC25519_KEYSIZE - i -1];
}

ForceZero(p, sizeof(p));
ForceZero(k, sizeof(k));
ForceZero(o, sizeof(o));

return err;
return ret;
}



/* curve25519 uses a serialized string for key representation */
int wc_ecc25519_export_public(ecc25519_key* key, byte* out, word32* outLen)
{
word32 keySz;
byte offset;

if (key == NULL || out == NULL)
if (key == NULL || out == NULL || outLen == NULL)
return BAD_FUNC_ARG;

/* check size of outgoing key */
keySz = wc_ecc25519_size(key);
offset = 2;

/* copy in public key and leave room for length and type byte */
XMEMCPY(out + offset, key->p.point, keySz);
*outLen = keySz + offset;

/* length and type */
out[0] = *outLen;
out[1] = key->f;
/* copy in public key */
XMEMCPY(out, key->p.point, keySz);
*outLen = keySz;

return 0;
}
Expand All @@ -206,21 +201,17 @@ int wc_ecc25519_export_public(ecc25519_key* key, byte* out, word32* outLen)
int wc_ecc25519_import_public(const byte* in, word32 inLen, ecc25519_key* key)
{
word32 keySz;
byte offset;

/* sanity check */
if (key == NULL || in == NULL)
return ECC_BAD_ARG_E;

/* check size of incoming keys */
keySz = wc_ecc25519_size(key);
offset = 2;

/* check that it is correct size plus length and type */
if ((inLen != keySz + offset) || (in[1] != MONTGOMERY_X_LE))
return ECC_BAD_ARG_E;
keySz = wc_ecc25519_size(key);
if (inLen != keySz)
return ECC_BAD_ARG_E;

XMEMCPY(key->p.point, in + offset, inLen);
XMEMCPY(key->p.point, in, inLen);

key->dp = &ecc25519_sets[0];

Expand All @@ -239,28 +230,24 @@ int wc_ecc25519_export_private_raw(ecc25519_key* key, byte* out, word32* outLen)
return ECC_BAD_ARG_E;

keySz = wc_ecc25519_size(key);

if (*outLen < keySz) {
*outLen = keySz;
return BUFFER_E;
}
*outLen = keySz;
XMEMSET(out, 0, *outLen);
XMEMCPY(out, key->k.point, *outLen);
XMEMSET(out, 0, keySz);
XMEMCPY(out, key->k.point, keySz);

return 0;
}


/* curve25519 private key import,public key in serialized format, private raw */
/* curve25519 private key import.
Public key to match private key needs to be imported too */
int wc_ecc25519_import_private_raw(const byte* priv, word32 privSz,
const byte* pub, word32 pubSz, ecc25519_key* key)
{
int ret = 0;
word32 keySz;

/* sanity check */
if (key == NULL || priv == NULL || pub ==NULL)
if (key == NULL || priv == NULL || pub == NULL)
return ECC_BAD_ARG_E;

/* check size of incoming keys */
Expand All @@ -283,7 +270,6 @@ int wc_ecc25519_init(ecc25519_key* key)
return ECC_BAD_ARG_E;

/* currently the format for curve25519 */
key->f = MONTGOMERY_X_LE;
key->dp = &ecc25519_sets[0];
keySz = key->dp->size;

Expand All @@ -294,9 +280,7 @@ int wc_ecc25519_init(ecc25519_key* key)
}


/**
Clean the memory of a key
*/
/* Clean the memory of a key */
void wc_ecc25519_free(ecc25519_key* key)
{
if (key == NULL)
Expand All @@ -308,7 +292,7 @@ void wc_ecc25519_free(ecc25519_key* key)
}


/* key size */
/* get key size */
int wc_ecc25519_size(ecc25519_key* key)
{
if (key == NULL) return 0;
Expand Down
94 changes: 80 additions & 14 deletions wolfcrypt/test/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -5162,6 +5162,50 @@ int ecc25519_test(void)
byte exportBuf[1024];
ecc25519_key userA, userB, pubKey;

/* test vectors from
https://tools.ietf.org/html/draft-josefsson-tls-curve25519-03
*/

/* secret key for party a */
byte sa[] = {
0x5A,0xC9,0x9F,0x33,0x63,0x2E,0x5A,0x76,
0x8D,0xE7,0xE8,0x1B,0xF8,0x54,0xC2,0x7C,
0x46,0xE3,0xFB,0xF2,0xAB,0xBA,0xCD,0x29,
0xEC,0x4A,0xFF,0x51,0x73,0x69,0xC6,0x60
};

/* public key for party a */
byte pa[] = {
0x05,0x7E,0x23,0xEA,0x9F,0x1C,0xBE,0x8A,
0x27,0x16,0x8F,0x6E,0x69,0x6A,0x79,0x1D,
0xE6,0x1D,0xD3,0xAF,0x7A,0xCD,0x4E,0xEA,
0xCC,0x6E,0x7B,0xA5,0x14,0xFD,0xA8,0x63
};

/* secret key for party b */
byte sb[] = {
0x47,0xDC,0x3D,0x21,0x41,0x74,0x82,0x0E,
0x11,0x54,0xB4,0x9B,0xC6,0xCD,0xB2,0xAB,
0xD4,0x5E,0xE9,0x58,0x17,0x05,0x5D,0x25,
0x5A,0xA3,0x58,0x31,0xB7,0x0D,0x32,0x60
};

/* public key for party b */
byte pb[] = {
0x6E,0xB8,0x9D,0xA9,0x19,0x89,0xAE,0x37,
0xC7,0xEA,0xC7,0x61,0x8D,0x9E,0x5C,0x49,
0x51,0xDB,0xA1,0xD7,0x3C,0x28,0x5A,0xE1,
0xCD,0x26,0xA8,0x55,0x02,0x0E,0xEF,0x04
};

/* expected shared key */
byte ss[] = {
0x61,0x45,0x0C,0xD9,0x8E,0x36,0x01,0x6B,
0x58,0x77,0x6A,0x89,0x7A,0x9F,0x0A,0xEF,
0x73,0x8B,0x99,0xF0,0x94,0x68,0xB8,0xD6,
0xB8,0x51,0x11,0x84,0xD5,0x34,0x94,0xAB
};

if (wc_InitRng(&rng) != 0)
return -1001;

Expand All @@ -5171,42 +5215,64 @@ int ecc25519_test(void)

/* make curve25519 keys */
if (wc_ecc25519_make_key(&rng, 32, &userA) != 0)
return -1014;
return -1002;

if (wc_ecc25519_make_key(&rng, 32, &userB) != 0)
return -1002;
return -1003;

/* find shared secret key */
x = sizeof(sharedA);
if (wc_ecc25519_shared_secret(&userA, &userB, sharedA, &x) != 0)
return -1015;
return -1004;

y = sizeof(sharedB);
if (wc_ecc25519_shared_secret(&userB, &userA, sharedB, &y) != 0)
return -1003;
return -1005;

/* compare shared secret keys to test they are the same */
if (y != x)
return -1004;
return -1006;

if (memcmp(sharedA, sharedB, x))
return -1005;
return -1007;

/* export a public key and import it for another user */
x = sizeof(exportBuf);
if (wc_ecc25519_export_public(&userA, exportBuf, &x) != 0)
return -1006;
return -1008;

if (wc_ecc25519_import_public(exportBuf, x, &pubKey) != 0)
return -1007;
return -1009;

/* test shared key after importing a public key */
y = sizeof(sharedB);
XMEMSET(sharedB, 0, sizeof(sharedB));
if (wc_ecc25519_shared_secret(&userB, &pubKey, sharedB, &y) != 0)
return -1008;
return -1010;

if (memcmp(sharedA, sharedB, y))
return -1010;
return -1011;

/* import RFC test vectors and compare shared key */
if (wc_ecc25519_import_private_raw(sa, sizeof(sa), pa, sizeof(pa), &userA)
!= 0)
return -1012;

if (wc_ecc25519_import_private_raw(sb, sizeof(sb), pb, sizeof(pb), &userB)
!= 0)
return -1013;

/* test against known test vector */
XMEMSET(sharedB, 0, sizeof(sharedB));
if (wc_ecc25519_shared_secret(&userA, &userB, sharedB, &y) != 0)
return -1014;

if (memcmp(ss, sharedB, y))
return -1015;

/* test swaping roles of keys and generating same shared key */
XMEMSET(sharedB, 0, sizeof(sharedB));
if (wc_ecc25519_shared_secret(&userB, &userA, sharedB, &y) != 0)
return -1016;

if (memcmp(ss, sharedB, y))
return -1017;

/* clean up keys when done */
wc_ecc25519_free(&pubKey);
Expand Down
2 changes: 0 additions & 2 deletions wolfssl/wolfcrypt/ecc25519.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,11 @@ typedef struct {

/* An ECC25519 Key */
typedef struct {
int type; /* Public or Private */
int idx; /* Index into the ecc_sets[] for the parameters of
this curve if -1, this key is using user supplied
curve in dp */
const ecc25519_set_type* dp; /* domain parameters, either points to
curves (idx >= 0) or user supplied */
byte f; /* format of key */
ECPoint p; /* public key */
ECPoint k; /* private key */
} ecc25519_key;
Expand Down

0 comments on commit 7ef362d

Please sign in to comment.