Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reabsed the p521 curve support on top of master #229

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
142 changes: 140 additions & 2 deletions curve-specific.inc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#define num_bytes_secp224r1 28
#define num_bytes_secp256r1 32
#define num_bytes_secp256k1 32
#define num_bytes_secp521r1 66

#if (uECC_WORD_SIZE == 1)

Expand All @@ -16,6 +17,7 @@
#define num_words_secp224r1 28
#define num_words_secp256r1 32
#define num_words_secp256k1 32
#define num_words_secp521r1 66

#define BYTES_TO_WORDS_8(a, b, c, d, e, f, g, h) \
0x##a, 0x##b, 0x##c, 0x##d, 0x##e, 0x##f, 0x##g, 0x##h
Expand All @@ -28,6 +30,7 @@
#define num_words_secp224r1 7
#define num_words_secp256r1 8
#define num_words_secp256k1 8
#define num_words_secp521r1 17

#define BYTES_TO_WORDS_8(a, b, c, d, e, f, g, h) 0x##d##c##b##a, 0x##h##g##f##e
#define BYTES_TO_WORDS_4(a, b, c, d) 0x##d##c##b##a
Expand All @@ -39,14 +42,16 @@
#define num_words_secp224r1 4
#define num_words_secp256r1 4
#define num_words_secp256k1 4
#define num_words_secp521r1 9

#define BYTES_TO_WORDS_8(a, b, c, d, e, f, g, h) 0x##h##g##f##e##d##c##b##a##ull
#define BYTES_TO_WORDS_4(a, b, c, d) 0x##d##c##b##a##ull

#endif /* uECC_WORD_SIZE */

#if uECC_SUPPORTS_secp160r1 || uECC_SUPPORTS_secp192r1 || \
uECC_SUPPORTS_secp224r1 || uECC_SUPPORTS_secp256r1
uECC_SUPPORTS_secp224r1 || uECC_SUPPORTS_secp256r1 || \
uECC_SUPPORTS_secp521r1
static void double_jacobian_default(uECC_word_t * X1,
uECC_word_t * Y1,
uECC_word_t * Z1,
Expand Down Expand Up @@ -108,7 +113,8 @@ static void x_side_default(uECC_word_t *result, const uECC_word_t *x, uECC_Curve

#if uECC_SUPPORT_COMPRESSED_POINT
#if uECC_SUPPORTS_secp160r1 || uECC_SUPPORTS_secp192r1 || \
uECC_SUPPORTS_secp256r1 || uECC_SUPPORTS_secp256k1
uECC_SUPPORTS_secp256r1 || uECC_SUPPORTS_secp256k1 || \
uECC_SUPPORTS_secp521r1
/* Compute a = sqrt(a) (mod curve_p). */
static void mod_sqrt_default(uECC_word_t *a, uECC_Curve curve) {
bitcount_t i;
Expand Down Expand Up @@ -1245,4 +1251,136 @@ static void omega_mult_secp256k1(uint64_t * result, const uint64_t * right) {

#endif /* uECC_SUPPORTS_secp256k1 */

#if uECC_SUPPORTS_secp521r1

#if (uECC_OPTIMIZATION_LEVEL > 0)
static void vli_mmod_fast_secp521r1(uECC_word_t *result, uECC_word_t *product);
#endif

static const struct uECC_Curve_t curve_secp521r1 = {
num_words_secp521r1,
num_bytes_secp521r1,
521, /* num_n_bits */
{
BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF),
BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF),
BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF),
BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF),
BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF),
BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF),
BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF),
BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF),
BYTES_TO_WORDS_4(FF, 01, 00, 00)
},
{
BYTES_TO_WORDS_8(09, 64, 38, 91, 1E, B7, 6F, BB),
BYTES_TO_WORDS_8(AE, 47, 9C, 89, B8, C9, B5, 3B),
BYTES_TO_WORDS_8(D0, A5, 09, F7, 48, 01, CC, 7F),
BYTES_TO_WORDS_8(6B, 96, 2F, BF, 83, 87, 86, 51),
BYTES_TO_WORDS_8(FA, FF, FF, FF, FF, FF, FF, FF),
BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF),
BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF),
BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF),
BYTES_TO_WORDS_4(FF, 01, 00, 00)
},
{
BYTES_TO_WORDS_8(66, BD, E5, C2, 31, 7E, 7E, F9),
BYTES_TO_WORDS_8(9B, 42, 6A, 85, C1, B3, 48, 33),
BYTES_TO_WORDS_8(DE, A8, FF, A2, 27, C1, 1D, FE),
BYTES_TO_WORDS_8(28, 59, E7, EF, 77, 5E, 4B, A1),
BYTES_TO_WORDS_8(BA, 3D, 4D, 6B, 60, AF, 28, F8),
BYTES_TO_WORDS_8(21, B5, 3F, 05, 39, 81, 64, 9C),
BYTES_TO_WORDS_8(42, B4, 95, 23, 66, CB, 3E, 9E),
BYTES_TO_WORDS_8(CD, E9, 04, 04, B7, 06, 8E, 85),
BYTES_TO_WORDS_4(C6, 00, 00, 00),

BYTES_TO_WORDS_8(50, 66, D1, 9F, 76, 94, BE, 88),
BYTES_TO_WORDS_8(40, C2, 72, A2, 86, 70, 3C, 35),
BYTES_TO_WORDS_8(61, 07, AD, 3F, 01, B9, 50, C5),
BYTES_TO_WORDS_8(40, 26, F4, 5E, 99, 72, EE, 97),
BYTES_TO_WORDS_8(2C, 66, 3E, 27, 17, BD, AF, 17),
BYTES_TO_WORDS_8(68, 44, 9B, 57, 49, 44, F5, 98),
BYTES_TO_WORDS_8(D9, 1B, 7D, 2C, B4, 5F, 8A, 5C),
BYTES_TO_WORDS_8(04, C0, 3B, 9A, 78, 6A, 29, 39),
BYTES_TO_WORDS_4(18, 01, 00, 00)
},
{
BYTES_TO_WORDS_8(00, 3F, 50, 6B, D4, 1F, 45, EF),
BYTES_TO_WORDS_8(F1, 34, 2C, 3D, 88, DF, 73, 35),
BYTES_TO_WORDS_8(07, BF, B1, 3B, BD, C0, 52, 16),
BYTES_TO_WORDS_8(7B, 93, 7E, EC, 51, 39, 19, 56),
BYTES_TO_WORDS_8(E1, 09, F1, 8E, 91, 89, B4, B8),
BYTES_TO_WORDS_8(F3, 15, B3, 99, 5B, 72, DA, A2),
BYTES_TO_WORDS_8(EE, 40, 85, B6, A0, 21, 9A, 92),
BYTES_TO_WORDS_8(1F, 9A, 1C, 8E, 61, B9, 3E, 95),
BYTES_TO_WORDS_4(51, 00, 00, 00)
},
&double_jacobian_default,
#if uECC_SUPPORT_COMPRESSED_POINT
&mod_sqrt_default,
#endif
&x_side_default,
#if (uECC_OPTIMIZATION_LEVEL > 0)
&vli_mmod_fast_secp521r1
#endif
};

uECC_Curve uECC_secp521r1(void) { return &curve_secp521r1; }

#if (uECC_OPTIMIZATION_LEVEL > 0)
/* Computes result = product % curve_p
from https://www.iad.gov/iad/customcf/openAttachment.cfm?FilePath=/iad/library/ia-guidance/ia-solutions-for-classified/algorithm-guidance/assets/public/upload/Mathematical-routines-for-the-NIST-prime-elliptic-curves.pdf&WpKes=aF6woL7fQp3dJiyEfkweRSR88VCgsUeRStm5D9 */
#if uECC_WORD_SIZE == 1
#error "Sorry, but secp521r1 is too complex for 8-bit computers!"
#elif uECC_WORD_SIZE == 4
static void vli_mmod_fast_secp521r1(uint32_t *result, uint32_t *product) {
uint32_t tmp[ num_words_secp521r1 ];
int carry;
int i;

/* t */
uECC_vli_set(result, product, num_words_secp521r1);

result[ num_words_secp521r1 - 1 ] &= 0x01FF;

/* s */
for ( i = 0; i < num_words_secp521r1 - 1; ++i ) {
tmp[ i ] = ( product[ num_words_secp521r1 - 1 + i ] >> 9 ) | ( product[ num_words_secp521r1 + i ] << 23 );
}
tmp[ num_words_secp521r1 - 1 ] = product[ 2 * num_words_secp521r1 - 2 ] >> 9;

carry = (int)uECC_vli_add(result, result, tmp, num_words_secp521r1);

while (carry || uECC_vli_cmp_unsafe(curve_secp521r1.p, result, num_words_secp521r1) != 1) {
carry -= uECC_vli_sub( result, result, curve_secp521r1.p, num_words_secp521r1);
}
}
#else
static void vli_mmod_fast_secp521r1(uint64_t *result, uint64_t *product) {
uint64_t tmp[ num_words_secp521r1 ];
int carry;
int i;

/* t */
uECC_vli_set(result, product, num_words_secp521r1);
result[ num_words_secp521r1 - 1 ] &= 0x01FF;

/* s */
for ( i = 0; i < num_words_secp521r1 - 1; ++i ) {
tmp[ i ] = ( product[ num_words_secp521r1 - 1 + i ] >> 9 ) | ( product[ num_words_secp521r1 + i ] << 55 );
}
tmp[ num_words_secp521r1 - 1 ] = product[ 2 * num_words_secp521r1 - 2 ] >> 9;

carry = (int)uECC_vli_add(result, result, tmp, num_words_secp521r1);

while (carry || uECC_vli_cmp_unsafe(curve_secp521r1.p, result, num_words_secp521r1) != 1) {
carry -= uECC_vli_sub( result, result, curve_secp521r1.p, num_words_secp521r1);
}
}
#endif
#endif /* uECC_OPTIMIZATION_LEVEL > 0 */


#endif /* uECC_SUPPORTS_secp521r1 */

#endif /* _UECC_CURVE_SPECIFIC_H_ */
27 changes: 15 additions & 12 deletions test/test_ecdh.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ void vli_print(uint8_t *vli, unsigned int size) {

int main() {
int i, c;
uint8_t private1[32] = {0};
uint8_t private2[32] = {0};
uint8_t public1[64] = {0};
uint8_t public2[64] = {0};
uint8_t secret1[32] = {0};
uint8_t secret2[32] = {0};
uint8_t private1[66] = {0};
uint8_t private2[66] = {0};
uint8_t public1[132] = {0};
uint8_t public2[132] = {0};
uint8_t secret1[66] = {0};
uint8_t secret2[66] = {0};

const struct uECC_Curve_t * curves[5];
int num_curves = 0;
Expand All @@ -37,6 +37,9 @@ int main() {
#if uECC_SUPPORTS_secp256k1
curves[num_curves++] = uECC_secp256k1();
#endif
#if uECC_SUPPORTS_secp521r1
curves[num_curves++] = uECC_secp521r1();
#endif

printf("Testing 256 random private key pairs\n");

Expand Down Expand Up @@ -64,22 +67,22 @@ int main() {
if (memcmp(secret1, secret2, sizeof(secret1)) != 0) {
printf("Shared secrets are not identical!\n");
printf("Private key 1 = ");
vli_print(private1, 32);
vli_print(private1, 66);
printf("\n");
printf("Private key 2 = ");
vli_print(private2, 32);
vli_print(private2, 66);
printf("\n");
printf("Public key 1 = ");
vli_print(public1, 64);
vli_print(public1, 132);
printf("\n");
printf("Public key 2 = ");
vli_print(public2, 64);
vli_print(public2, 132);
printf("\n");
printf("Shared secret 1 = ");
vli_print(secret1, 32);
vli_print(secret1, 66);
printf("\n");
printf("Shared secret 2 = ");
vli_print(secret2, 32);
vli_print(secret2, 66);
printf("\n");
}
}
Expand Down
13 changes: 8 additions & 5 deletions test/test_ecdsa.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@

int main() {
int i, c;
uint8_t private[32] = {0};
uint8_t public[64] = {0};
uint8_t hash[32] = {0};
uint8_t sig[64] = {0};
uint8_t private[66] = {0};
uint8_t public[132] = {0};
uint8_t hash[66] = {0};
uint8_t sig[132] = {0};

const struct uECC_Curve_t * curves[5];
const struct uECC_Curve_t * curves[6];
int num_curves = 0;
#if uECC_SUPPORTS_secp160r1
curves[num_curves++] = uECC_secp160r1();
Expand All @@ -29,6 +29,9 @@ int main() {
#if uECC_SUPPORTS_secp256k1
curves[num_curves++] = uECC_secp256k1();
#endif
#if uECC_SUPPORTS_secp521r1
curves[num_curves++] = uECC_secp521r1();
#endif

printf("Testing 256 signatures\n");
for (c = 0; c < num_curves; ++c) {
Expand Down
12 changes: 12 additions & 0 deletions uECC.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@
#undef uECC_MAX_WORDS
#define uECC_MAX_WORDS 32
#endif
#if uECC_SUPPORTS_secp521r1
#undef uECC_MAX_WORDS
#define uECC_MAX_WORDS 66
#endif
#elif (uECC_WORD_SIZE == 4)
#if uECC_SUPPORTS_secp160r1
#define uECC_MAX_WORDS 6 /* Due to the size of curve_n. */
Expand All @@ -120,6 +124,10 @@
#undef uECC_MAX_WORDS
#define uECC_MAX_WORDS 8
#endif
#if uECC_SUPPORTS_secp521r1
#undef uECC_MAX_WORDS
#define uECC_MAX_WORDS 17
#endif
#elif (uECC_WORD_SIZE == 8)
#if uECC_SUPPORTS_secp160r1
#define uECC_MAX_WORDS 3
Expand All @@ -136,6 +144,10 @@
#undef uECC_MAX_WORDS
#define uECC_MAX_WORDS 4
#endif
#if uECC_SUPPORTS_secp521r1
#undef uECC_MAX_WORDS
#define uECC_MAX_WORDS 9
#endif
#endif /* uECC_WORD_SIZE */

#define BITS_TO_WORDS(num_bits) ((num_bits + ((uECC_WORD_SIZE * 8) - 1)) / (uECC_WORD_SIZE * 8))
Expand Down
6 changes: 6 additions & 0 deletions uECC.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ the same endianness. */
#ifndef uECC_SUPPORTS_secp256k1
#define uECC_SUPPORTS_secp256k1 1
#endif
#ifndef uECC_SUPPORTS_secp521r1
#define uECC_SUPPORTS_secp521r1 1
#endif

/* Specifies whether compressed point format is supported.
Set to 0 to disable point compression/decompression functions. */
Expand Down Expand Up @@ -98,6 +101,9 @@ uECC_Curve uECC_secp256r1(void);
#if uECC_SUPPORTS_secp256k1
uECC_Curve uECC_secp256k1(void);
#endif
#if uECC_SUPPORTS_secp521r1
uECC_Curve uECC_secp521r1(void);
#endif

/* uECC_RNG_Function type
The RNG function should fill 'size' random bytes into 'dest'. It should return 1 if
Expand Down