From d7add23ee0dd587908197295a778f0b936098330 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nenad=20Miks=C3=83=C2=8C=C3=82=C2=8Ca?= Date: Wed, 9 Aug 2017 12:33:44 +0200 Subject: [PATCH 1/7] initial support for P-521 --- curve-specific.inc | 109 ++++++++++++++++++++++++++++++++++++++++++++- uECC.c | 12 +++++ uECC.h | 6 +++ 3 files changed, 125 insertions(+), 2 deletions(-) diff --git a/curve-specific.inc b/curve-specific.inc index 0453b21..6abea3e 100644 --- a/curve-specific.inc +++ b/curve-specific.inc @@ -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) @@ -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 @@ -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 @@ -39,6 +42,7 @@ #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 @@ -46,7 +50,8 @@ #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, @@ -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; @@ -1245,4 +1251,103 @@ 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 */ +static void vli_mmod_fast_secp521r1(uECC_word_t *result, uECC_word_t *product) { + uECC_word_t tmp[ num_words_secp521r1 ]; + int carry; + + /* t */ + uECC_vli_set(result, product, num_words_secp521r1); + /* s */ + uECC_vli_set(tmp, product + num_words_secp521r1, num_words_secp521r1); + + 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 /* uECC_OPTIMIZATION_LEVEL > 0 */ + + +#endif /* uECC_SUPPORTS_secp521r1 */ + #endif /* _UECC_CURVE_SPECIFIC_H_ */ diff --git a/uECC.c b/uECC.c index a3d502c..8ad4036 100644 --- a/uECC.c +++ b/uECC.c @@ -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. */ @@ -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 @@ -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)) diff --git a/uECC.h b/uECC.h index dcbdbfa..dcd82b9 100644 --- a/uECC.h +++ b/uECC.h @@ -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. */ @@ -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 From 475f38ae3500d46c9f15f6214c5cb10e23c04f69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nenad=20Miks=CC=8Ca?= Date: Thu, 10 Aug 2017 18:35:09 +0200 Subject: [PATCH 2/7] avoid infinite loop in optimised mmod for secp521r1 --- curve-specific.inc | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/curve-specific.inc b/curve-specific.inc index 6abea3e..24ed259 100644 --- a/curve-specific.inc +++ b/curve-specific.inc @@ -1330,18 +1330,26 @@ 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 */ -static void vli_mmod_fast_secp521r1(uECC_word_t *result, uECC_word_t *product) { - uECC_word_t tmp[ num_words_secp521r1 ]; +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 */ - uECC_vli_set(tmp, product + num_words_secp521r1, num_words_secp521r1); + for ( i = 0; i < num_words_secp521r1 - 2; ++i ) { + tmp[ i ] = ( product[ num_words_secp521r1 - 1 + i ] >> 9 ) | ( product[ num_words_secp521r1 + i ] << 55 ); + } + tmp[ num_words_secp521r1 - 1 ] = ( product[ num_words_secp521r1 + num_words_secp521r1 - 1 ] >> 9 ) & 0x01FF; 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); + carry -= uECC_vli_sub( result, result, curve_secp521r1.p, num_words_secp521r1); } } From c89c032fb24462e0d7a4dd63951f25631a5c062a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nenad=20Miks=CC=8Ca?= Date: Thu, 10 Aug 2017 18:36:41 +0200 Subject: [PATCH 3/7] added tests for secp521r1 --- test/test_ecdh.c | 15 +++++++++------ test/test_ecdsa.c | 13 ++++++++----- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/test/test_ecdh.c b/test/test_ecdh.c index 7315b75..9a249e5 100644 --- a/test/test_ecdh.c +++ b/test/test_ecdh.c @@ -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; @@ -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"); diff --git a/test/test_ecdsa.c b/test/test_ecdsa.c index 8699794..d9b5d39 100644 --- a/test/test_ecdsa.c +++ b/test/test_ecdsa.c @@ -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(); @@ -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) { From 2f05d85c3541e879251321f975a6c0a3c9438346 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nenad=20Miks=C3=8C=C2=8Ca?= Date: Thu, 10 Aug 2017 19:11:54 +0200 Subject: [PATCH 4/7] added 32-bit implementation of optimised secp521r1 mmod - the implementation does not work for unknown reason, but gives overview of final performance of P-521 - details can be tracked here: https://github.com/kmackay/micro-ecc/issues/99#issuecomment-321605088 --- curve-specific.inc | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/curve-specific.inc b/curve-specific.inc index 24ed259..e71ba0c 100644 --- a/curve-specific.inc +++ b/curve-specific.inc @@ -1330,6 +1330,32 @@ 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 == 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 - 2; ++i ) { + tmp[ i ] = ( product[ num_words_secp521r1 - 1 + i ] >> 9 ) | ( product[ num_words_secp521r1 + i ] << 23 ); + } + tmp[ num_words_secp521r1 - 1 ] = ( product[ num_words_secp521r1 + num_words_secp521r1 - 1 ] >> 9 ) & 0x01FF; + + 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; @@ -1353,6 +1379,7 @@ static void vli_mmod_fast_secp521r1(uint64_t *result, uint64_t *product) { } } +#endif #endif /* uECC_OPTIMIZATION_LEVEL > 0 */ From b8851f839a2ed4588616377a343edd62486f3a33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nenad=20Miks=CC=8Ca?= Date: Sun, 13 Aug 2017 15:15:34 +0200 Subject: [PATCH 5/7] fixed mmod function for secp521r1, thanks to https://github.com/kmackay/micro-ecc/issues/99#issuecomment-321992718 - secp521r1 currently works only for uECC_OPTIMIZATION_LEVEL <= 2 and is around 6 times slower than secp256k1 on same optimisation level and around 12 time slower than secp256k1 on optimisation level 4 --- curve-specific.inc | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/curve-specific.inc b/curve-specific.inc index e71ba0c..b2de812 100644 --- a/curve-specific.inc +++ b/curve-specific.inc @@ -1343,17 +1343,16 @@ static void vli_mmod_fast_secp521r1(uint32_t *result, uint32_t *product) { result[ num_words_secp521r1 - 1 ] &= 0x01FF; /* s */ - for ( i = 0; i < num_words_secp521r1 - 2; ++i ) { + 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[ num_words_secp521r1 + num_words_secp521r1 - 1 ] >> 9 ) & 0x01FF; + 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) { @@ -1363,21 +1362,19 @@ static void vli_mmod_fast_secp521r1(uint64_t *result, uint64_t *product) { /* t */ uECC_vli_set(result, product, num_words_secp521r1); - result[ num_words_secp521r1 - 1 ] &= 0x01FF; /* s */ - for ( i = 0; i < num_words_secp521r1 - 2; ++i ) { + 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[ num_words_secp521r1 + num_words_secp521r1 - 1 ] >> 9 ) & 0x01FF; + 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 */ From 7d37a5cf54fcd8ca77e6eb26447375135a9ff786 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nenad=20Miks=CC=8Ca?= Date: Sun, 13 Aug 2017 16:00:45 +0200 Subject: [PATCH 6/7] raise a compile error when someone attempts to enable secp521r1 on 8-bit computer --- curve-specific.inc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/curve-specific.inc b/curve-specific.inc index b2de812..368fa14 100644 --- a/curve-specific.inc +++ b/curve-specific.inc @@ -1330,8 +1330,9 @@ 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 == 4 +#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; From 1c56c42002000ef9693211e5c9e8facac8e2632a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nenad=20Miks=CC=8Ca?= Date: Sun, 13 Aug 2017 16:33:39 +0200 Subject: [PATCH 7/7] fix printing of secrets and keys in P-521 mode --- test/test_ecdh.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/test_ecdh.c b/test/test_ecdh.c index 9a249e5..74ce3cc 100644 --- a/test/test_ecdh.c +++ b/test/test_ecdh.c @@ -67,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"); } }