From 74f6d2d9d7fa2f5c54985c826798ca124abf9236 Mon Sep 17 00:00:00 2001 From: Ken MacKay Date: Wed, 26 Aug 2015 23:10:46 -0700 Subject: [PATCH] Directly expose vli functions if uECC_ENABLE_VLI_API != 0 Added a header file for those functions as well. --- asm_arm.inc | 56 ++-- asm_avr.inc | 58 ++-- curve-specific.inc | 416 ++++++++++++------------- platform-specific.inc | 97 +----- types.inc | 103 +++++++ uECC.c | 695 ++++++++++++++++++------------------------ uECC.h | 4 +- uECC_vli.h | 149 +++++++++ 8 files changed, 815 insertions(+), 763 deletions(-) create mode 100644 types.inc create mode 100644 uECC_vli.h diff --git a/asm_arm.inc b/asm_arm.inc index d5bbe57..f71e89d 100644 --- a/asm_arm.inc +++ b/asm_arm.inc @@ -37,10 +37,10 @@ #if (uECC_OPTIMIZATION_LEVEL >= 2) -static uECC_word_t vli_add(uECC_word_t *result, - const uECC_word_t *left, - const uECC_word_t *right, - wordcount_t num_words) { +uECC_VLI_API uECC_word_t uECC_vli_add(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words) { #if (uECC_PLATFORM == uECC_arm_thumb) || (uECC_PLATFORM == uECC_arm_thumb2) uint32_t jump = ((uECC_MAX_WORDS - num_words) * 4 + 5) * 2 + 1; #else /* ARM */ @@ -113,10 +113,10 @@ static uECC_word_t vli_add(uECC_word_t *result, } #define asm_add 1 -static uECC_word_t vli_sub(uECC_word_t *result, - const uECC_word_t *left, - const uECC_word_t *right, - wordcount_t num_words) { +uECC_VLI_API uECC_word_t uECC_vli_sub(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words) { #if (uECC_PLATFORM == uECC_arm_thumb) || (uECC_PLATFORM == uECC_arm_thumb2) uint32_t jump = ((uECC_MAX_WORDS - num_words) * 4 + 5) * 2 + 1; #else /* ARM */ @@ -528,10 +528,10 @@ static uECC_word_t vli_sub(uECC_word_t *result, "stmia r0!, {r11, r12} \n\t" #if (uECC_PLATFORM != uECC_arm_thumb) -static void vli_mult(uint32_t *result, - const uint32_t *left, - const uint32_t *right, - wordcount_t num_words) { +uECC_VLI_API void uECC_vli_mult(uint32_t *result, + const uint32_t *left, + const uint32_t *right, + wordcount_t num_words) { register uint32_t *r0 __asm__("r0") = result; register const uint32_t *r1 __asm__("r1") = left; register const uint32_t *r2 __asm__("r2") = right; @@ -794,7 +794,9 @@ static void vli_mult(uint32_t *result, "adc r5, r12 \n\t" \ "stmia r0!, {r4, r5} \n\t" -static void vli_square(uECC_word_t *result, const uECC_word_t *left, wordcount_t num_words) { +uECC_VLI_API void uECC_vli_square(uECC_word_t *result, + const uECC_word_t *left, + wordcount_t num_words) { register uint32_t *r0 __asm__("r0") = result; register const uint32_t *r1 __asm__("r1") = left; register uint32_t r2 __asm__("r2") = num_words; @@ -855,10 +857,10 @@ static void vli_square(uECC_word_t *result, const uECC_word_t *left, wordcount_t /* ---- "Small" implementations ---- */ #if !asm_add -static uECC_word_t vli_add(uECC_word_t *result, - const uECC_word_t *left, - const uECC_word_t *right, - wordcount_t num_words) { +uECC_VLI_API uECC_word_t uECC_vli_add(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words) { uint32_t carry = 0; uint32_t left_word; uint32_t right_word; @@ -887,10 +889,10 @@ static uECC_word_t vli_add(uECC_word_t *result, #endif #if !asm_sub -static uECC_word_t vli_sub(uECC_word_t *result, - const uECC_word_t *left, - const uECC_word_t *right, - wordcount_t num_words) { +uECC_VLI_API uECC_word_t uECC_vli_sub(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words) { uint32_t carry = 1; /* carry = 1 initially (means don't borrow) */ uint32_t left_word; uint32_t right_word; @@ -919,10 +921,10 @@ static uECC_word_t vli_sub(uECC_word_t *result, #endif #if !asm_mult -static void vli_mult(uECC_word_t *result, - const uECC_word_t *left, - const uECC_word_t *right, - wordcount_t num_words) { +uECC_VLI_API void uECC_vli_mult(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words) { #if (uECC_PLATFORM != uECC_arm_thumb) uint32_t c0 = 0; uint32_t c1 = 0; @@ -1080,7 +1082,9 @@ static void vli_mult(uECC_word_t *result, #if uECC_SQUARE_FUNC #if !asm_square -static void vli_square(uECC_word_t *result, const uECC_word_t *left, wordcount_t num_words) { +uECC_VLI_API void uECC_vli_square(uECC_word_t *result, + const uECC_word_t *left, + wordcount_t num_words) { #if (uECC_PLATFORM != uECC_arm_thumb) uint32_t c0 = 0; uint32_t c1 = 0; diff --git a/asm_avr.inc b/asm_avr.inc index 08b996f..9f59dae 100644 --- a/asm_avr.inc +++ b/asm_avr.inc @@ -45,7 +45,7 @@ #if (uECC_ASM == uECC_asm_fast) -static void vli_clear(uint8_t *vli) { +uECC_VLI_API void uECC_vli_clear(uint8_t *vli) { __asm__ volatile ( REPEAT(uECC_BYTES, "st %a[ptr]+, r1 \n\t") @@ -56,7 +56,7 @@ static void vli_clear(uint8_t *vli) { } #define asm_clear 1 -static void vli_set(uint8_t *dest, const uint8_t *src) { +uECC_VLI_API void uECC_vli_set(uint8_t *dest, const uint8_t *src) { __asm__ volatile ( REPEAT(uECC_BYTES, "ld r0, %a[sptr]+ \n\t" @@ -68,7 +68,7 @@ static void vli_set(uint8_t *dest, const uint8_t *src) { } #define asm_set 1 -static void vli_rshift1(uint8_t *vli) { +uECC_VLI_API void uECC_vli_rshift1(uint8_t *vli) { __asm__ volatile ( "adiw r30, " STR(uECC_BYTES) " \n\t" "ld r0, -z \n\t" /* Load byte. */ @@ -88,7 +88,7 @@ static void vli_rshift1(uint8_t *vli) { #define asm_rshift1 1 /* Computes result = left + right, returning carry. Can modify in place. */ -static uint8_t vli_add(uint8_t *result, const uint8_t *left, const uint8_t *right) { +uECC_VLI_API uint8_t uECC_vli_add(uint8_t *result, const uint8_t *left, const uint8_t *right) { uint8_t carry = 0; uint8_t left_byte; uint8_t right_byte; @@ -119,7 +119,7 @@ static uint8_t vli_add(uint8_t *result, const uint8_t *left, const uint8_t *righ #define asm_add 1 /* Computes result = left - right, returning borrow. Can modify in place. */ -static uint8_t vli_sub(uint8_t *result, const uint8_t *left, const uint8_t *right) { +uECC_VLI_API uint8_t uECC_vli_sub(uint8_t *result, const uint8_t *left, const uint8_t *right) { uint8_t borrow = 0; uint8_t left_byte; uint8_t right_byte; @@ -151,7 +151,7 @@ static uint8_t vli_sub(uint8_t *result, const uint8_t *left, const uint8_t *righ #if (uECC_BYTES == 20) __attribute((noinline)) -static void vli_mult(uint8_t *result, const uint8_t *left, const uint8_t *right) { +uECC_VLI_API void uECC_vli_mult(uint8_t *result, const uint8_t *left, const uint8_t *right) { __asm__ volatile ( "adiw r30, 10 \n\t" "adiw r28, 10 \n\t" @@ -2066,7 +2066,7 @@ static void vli_mult(uint8_t *result, const uint8_t *left, const uint8_t *right) #define asm_mult 1 #elif (uECC_BYTES == 24) __attribute((noinline)) -static void vli_mult(uint8_t *result, const uint8_t *left, const uint8_t *right) { +uECC_VLI_API void uECC_vli_mult(uint8_t *result, const uint8_t *left, const uint8_t *right) { __asm__ volatile ( "adiw r30, 20 \n\t" "adiw r28, 20 \n\t" @@ -4849,7 +4849,7 @@ static void vli_mult(uint8_t *result, const uint8_t *left, const uint8_t *right) #define asm_mult 1 #elif (uECC_BYTES == 28) __attribute((noinline)) -static void vli_mult(uint8_t *result, const uint8_t *left, const uint8_t *right) { +uECC_VLI_API void uECC_vli_mult(uint8_t *result, const uint8_t *left, const uint8_t *right) { __asm__ volatile ( "adiw r30, 20 \n\t" "adiw r28, 20 \n\t" @@ -8619,7 +8619,7 @@ static void vli_mult(uint8_t *result, const uint8_t *left, const uint8_t *right) #define asm_mult 1 #elif (uECC_BYTES == 32) __attribute((noinline)) -static void vli_mult(uint8_t *result, const uint8_t *left, const uint8_t *right) { +uECC_VLI_API void uECC_vli_mult(uint8_t *result, const uint8_t *left, const uint8_t *right) { __asm__ volatile ( "adiw r30, 30 \n\t" "adiw r28, 30 \n\t" @@ -13549,7 +13549,7 @@ static void vli_mult(uint8_t *result, const uint8_t *left, const uint8_t *right) #if (uECC_BYTES == 20) // Inlining is allowed because y (r28, r29) is not used. -static void vli_square(uint8_t *result, const uint8_t *left) { +uECC_VLI_API void uECC_vli_square(uint8_t *result, const uint8_t *left) { __asm__ volatile ( "ld r2, x+ \n\t" "ld r3, x+ \n\t" @@ -14716,7 +14716,7 @@ static void vli_square(uint8_t *result, const uint8_t *left) { #elif (uECC_BYTES == 24) __attribute((noinline)) -static void vli_square(uint8_t *result, const uint8_t *left) { +uECC_VLI_API void uECC_vli_square(uint8_t *result, const uint8_t *left) { __asm__ volatile ( "ldi r25, 0 \n\t" "movw r28, r26 \n\t" @@ -16375,7 +16375,7 @@ static void vli_square(uint8_t *result, const uint8_t *left) { #elif (uECC_BYTES == 28) __attribute((noinline)) -static void vli_square(uint8_t *result, const uint8_t *left) { +uECC_VLI_API void uECC_vli_square(uint8_t *result, const uint8_t *left) { __asm__ volatile ( "ldi r25, 0 \n\t" "movw r28, r26 \n\t" @@ -18590,7 +18590,7 @@ static void vli_square(uint8_t *result, const uint8_t *left) { #elif (uECC_BYTES == 32) __attribute((noinline)) -static void vli_square(uint8_t *result, const uint8_t *left) { +uECC_VLI_API void uECC_vli_square(uint8_t *result, const uint8_t *left) { __asm__ volatile ( "ldi r25, 0 \n\t" "movw r28, r26 \n\t" @@ -21425,7 +21425,7 @@ static void vli_square(uint8_t *result, const uint8_t *left) { #endif /* uECC_BYTES == xx */ #endif /* uECC_SQUARE_FUNC */ -static void vli_modSub_fast(uint8_t *result, const uint8_t *left, const uint8_t *right) { +uECC_VLI_API void uECC_vli_modSub_fast(uint8_t *result, const uint8_t *left, const uint8_t *right) { uint8_t t1, t2; __asm__ volatile ( "push r28 \n\t" /* Save Y */ @@ -21475,7 +21475,7 @@ static void vli_modSub_fast(uint8_t *result, const uint8_t *left, const uint8_t #define asm_modSub_fast 1 #if uECC_CURVE == uECC_secp160r1 -static void vli_mmod_fast(uint8_t *RESTRICT result, uint8_t *RESTRICT product) { +uECC_VLI_API void uECC_vli_mmod_fast(uint8_t *RESTRICT result, uint8_t *RESTRICT product) { uint8_t carry = 0; __asm__ volatile ( "in r30, __SP_L__ \n\t" @@ -21649,19 +21649,19 @@ static void vli_mmod_fast(uint8_t *RESTRICT result, uint8_t *RESTRICT product) { if (carry > 0) { --carry; - vli_sub(result, result, curve_p); + uECC_vli_sub(result, result, curve_p); } if (carry > 0) { - vli_sub(result, result, curve_p); + uECC_vli_sub(result, result, curve_p); } - if (vli_cmp(result, curve_p) > 0) { - vli_sub(result, result, curve_p); + if (uECC_vli_cmp(result, curve_p) > 0) { + uECC_vli_sub(result, result, curve_p); } } #define asm_mmod_fast 1 #elif (uECC_CURVE == uECC_secp256k1) -static void vli_mmod_fast(uint8_t *RESTRICT result, uint8_t *RESTRICT product) { +uECC_VLI_API void uECC_vli_mmod_fast(uint8_t *RESTRICT result, uint8_t *RESTRICT product) { uint8_t carry = 0; __asm__ volatile ( "in r30, __SP_L__ \n\t" @@ -21972,13 +21972,13 @@ static void vli_mmod_fast(uint8_t *RESTRICT result, uint8_t *RESTRICT product) { if (carry > 0) { --carry; - vli_sub(result, result, curve_p); + uECC_vli_sub(result, result, curve_p); } if (carry > 0) { - vli_sub(result, result, curve_p); + uECC_vli_sub(result, result, curve_p); } - if (vli_cmp(result, curve_p) > 0) { - vli_sub(result, result, curve_p); + if (uECC_vli_cmp(result, curve_p) > 0) { + uECC_vli_sub(result, result, curve_p); } } #define asm_mmod_fast 1 @@ -21988,7 +21988,7 @@ static void vli_mmod_fast(uint8_t *RESTRICT result, uint8_t *RESTRICT product) { #endif /* (uECC_ASM == uECC_asm_fast) */ #if !asm_rshift1 -static void vli_rshift1(uint8_t *vli) { +uECC_VLI_API void uECC_vli_rshift1(uint8_t *vli) { uint8_t i = uECC_BYTES; __asm__ volatile ( "adiw r30, " STR(uECC_BYTES) " \n\t" @@ -22010,7 +22010,7 @@ static void vli_rshift1(uint8_t *vli) { #endif #if !asm_add -static uint8_t vli_add(uint8_t *result, const uint8_t *left, const uint8_t *right) { +uECC_VLI_API uint8_t uECC_vli_add(uint8_t *result, const uint8_t *left, const uint8_t *right) { uint8_t i = uECC_BYTES; uint8_t carry = 0; uint8_t left_byte; @@ -22041,7 +22041,7 @@ static uint8_t vli_add(uint8_t *result, const uint8_t *left, const uint8_t *righ #endif #if !asm_sub -static uint8_t vli_sub(uint8_t *result, const uint8_t *left, const uint8_t *right) { +uECC_VLI_API uint8_t uECC_vli_sub(uint8_t *result, const uint8_t *left, const uint8_t *right) { uint8_t i = uECC_BYTES; uint8_t borrow = 0; uint8_t left_byte; @@ -22073,7 +22073,7 @@ static uint8_t vli_sub(uint8_t *result, const uint8_t *left, const uint8_t *righ #if !asm_mult __attribute((noinline)) -static void vli_mult(uint8_t *result, const uint8_t *left, const uint8_t *right) { +uECC_VLI_API void uECC_vli_mult(uint8_t *result, const uint8_t *left, const uint8_t *right) { uint8_t r0 = 0; uint8_t r1 = 0; uint8_t r2 = 0; @@ -22166,7 +22166,7 @@ static void vli_mult(uint8_t *result, const uint8_t *left, const uint8_t *right) #if uECC_SQUARE_FUNC #if !asm_square -static void vli_square(uint8_t *result, const uint8_t *left) { +uECC_VLI_API void uECC_vli_square(uint8_t *result, const uint8_t *left) { uint8_t r0 = 0; uint8_t r1 = 0; uint8_t r2 = 0; diff --git a/curve-specific.inc b/curve-specific.inc index 60f5d18..fa9a7dc 100644 --- a/curve-specific.inc +++ b/curve-specific.inc @@ -59,42 +59,42 @@ static void double_jacobian_default(uECC_word_t * X1, uECC_word_t t4[uECC_MAX_WORDS]; uECC_word_t t5[uECC_MAX_WORDS]; - if (vli_isZero(Z1, curve->num_words)) { + if (uECC_vli_isZero(Z1, curve->num_words)) { return; } - vli_modSquare_fast(t4, Y1, curve); /* t4 = y1^2 */ - vli_modMult_fast(t5, X1, t4, curve); /* t5 = x1*y1^2 = A */ - vli_modSquare_fast(t4, t4, curve); /* t4 = y1^4 */ - vli_modMult_fast(Y1, Y1, Z1, curve); /* t2 = y1*z1 = z3 */ - vli_modSquare_fast(Z1, Z1, curve); /* t3 = z1^2 */ + uECC_vli_modSquare_fast(t4, Y1, curve); /* t4 = y1^2 */ + uECC_vli_modMult_fast(t5, X1, t4, curve); /* t5 = x1*y1^2 = A */ + uECC_vli_modSquare_fast(t4, t4, curve); /* t4 = y1^4 */ + uECC_vli_modMult_fast(Y1, Y1, Z1, curve); /* t2 = y1*z1 = z3 */ + uECC_vli_modSquare_fast(Z1, Z1, curve); /* t3 = z1^2 */ - vli_modAdd(X1, X1, Z1, curve->p, curve->num_words); /* t1 = x1 + z1^2 */ - vli_modAdd(Z1, Z1, Z1, curve->p, curve->num_words); /* t3 = 2*z1^2 */ - vli_modSub(Z1, X1, Z1, curve->p, curve->num_words); /* t3 = x1 - z1^2 */ - vli_modMult_fast(X1, X1, Z1, curve); /* t1 = x1^2 - z1^4 */ + uECC_vli_modAdd(X1, X1, Z1, curve->p, curve->num_words); /* t1 = x1 + z1^2 */ + uECC_vli_modAdd(Z1, Z1, Z1, curve->p, curve->num_words); /* t3 = 2*z1^2 */ + uECC_vli_modSub(Z1, X1, Z1, curve->p, curve->num_words); /* t3 = x1 - z1^2 */ + uECC_vli_modMult_fast(X1, X1, Z1, curve); /* t1 = x1^2 - z1^4 */ - vli_modAdd(Z1, X1, X1, curve->p, curve->num_words); /* t3 = 2*(x1^2 - z1^4) */ - vli_modAdd(X1, X1, Z1, curve->p, curve->num_words); /* t1 = 3*(x1^2 - z1^4) */ - if (vli_testBit(X1, 0)) { - uECC_word_t l_carry = vli_add(X1, X1, curve->p, curve->num_words); - vli_rshift1(X1, curve->num_words); + uECC_vli_modAdd(Z1, X1, X1, curve->p, curve->num_words); /* t3 = 2*(x1^2 - z1^4) */ + uECC_vli_modAdd(X1, X1, Z1, curve->p, curve->num_words); /* t1 = 3*(x1^2 - z1^4) */ + if (uECC_vli_testBit(X1, 0)) { + uECC_word_t l_carry = uECC_vli_add(X1, X1, curve->p, curve->num_words); + uECC_vli_rshift1(X1, curve->num_words); X1[curve->num_words - 1] |= l_carry << (uECC_WORD_BITS - 1); } else { - vli_rshift1(X1, curve->num_words); + uECC_vli_rshift1(X1, curve->num_words); } /* t1 = 3/2*(x1^2 - z1^4) = B */ - vli_modSquare_fast(Z1, X1, curve); /* t3 = B^2 */ - vli_modSub(Z1, Z1, t5, curve->p, curve->num_words); /* t3 = B^2 - A */ - vli_modSub(Z1, Z1, t5, curve->p, curve->num_words); /* t3 = B^2 - 2A = x3 */ - vli_modSub(t5, t5, Z1, curve->p, curve->num_words); /* t5 = A - x3 */ - vli_modMult_fast(X1, X1, t5, curve); /* t1 = B * (A - x3) */ - vli_modSub(t4, X1, t4, curve->p, curve->num_words); /* t4 = B * (A - x3) - y1^4 = y3 */ + uECC_vli_modSquare_fast(Z1, X1, curve); /* t3 = B^2 */ + uECC_vli_modSub(Z1, Z1, t5, curve->p, curve->num_words); /* t3 = B^2 - A */ + uECC_vli_modSub(Z1, Z1, t5, curve->p, curve->num_words); /* t3 = B^2 - 2A = x3 */ + uECC_vli_modSub(t5, t5, Z1, curve->p, curve->num_words); /* t5 = A - x3 */ + uECC_vli_modMult_fast(X1, X1, t5, curve); /* t1 = B * (A - x3) */ + uECC_vli_modSub(t4, X1, t4, curve->p, curve->num_words); /* t4 = B * (A - x3) - y1^4 = y3 */ - vli_set(X1, Z1, curve->num_words); - vli_set(Z1, Y1, curve->num_words); - vli_set(Y1, t4, curve->num_words); + uECC_vli_set(X1, Z1, curve->num_words); + uECC_vli_set(Z1, Y1, curve->num_words); + uECC_vli_set(Y1, t4, curve->num_words); } #if uECC_SUPPORT_COMPRESSED_POINT @@ -106,14 +106,14 @@ static void mod_sqrt_default(uECC_word_t *a, uECC_Curve curve) { /* When curve->p == 3 (mod 4), we can compute sqrt(a) = a^((curve->p + 1) / 4) (mod curve->p). */ - vli_add(p1, curve->p, p1, curve->num_words); /* p1 = curve_p + 1 */ - for (i = vli_numBits(p1, curve->num_words) - 1; i > 1; --i) { - vli_modSquare_fast(l_result, l_result, curve); - if (vli_testBit(p1, i)) { - vli_modMult_fast(l_result, l_result, a, curve); + uECC_vli_add(p1, curve->p, p1, curve->num_words); /* p1 = curve_p + 1 */ + for (i = uECC_vli_numBits(p1, curve->num_words) - 1; i > 1; --i) { + uECC_vli_modSquare_fast(l_result, l_result, curve); + if (uECC_vli_testBit(p1, i)) { + uECC_vli_modMult_fast(l_result, l_result, a, curve); } } - vli_set(a, l_result, curve->num_words); + uECC_vli_set(a, l_result, curve->num_words); } #endif @@ -121,10 +121,10 @@ static void mod_sqrt_default(uECC_word_t *a, uECC_Curve curve) { static void x_side_default(uECC_word_t *result, const uECC_word_t *x, uECC_Curve curve) { uECC_word_t _3[uECC_MAX_WORDS] = {3}; /* -a = 3 */ - vli_modSquare_fast(result, x, curve); /* r = x^2 */ - vli_modSub(result, result, _3, curve->p, curve->num_words); /* r = x^2 - 3 */ - vli_modMult_fast(result, result, x, curve); /* r = x^3 - 3x */ - vli_modAdd(result, result, curve->b, curve->p, curve->num_words); /* r = x^3 - 3x + b */ + uECC_vli_modSquare_fast(result, x, curve); /* r = x^2 */ + uECC_vli_modSub(result, result, _3, curve->p, curve->num_words); /* r = x^2 - 3 */ + uECC_vli_modMult_fast(result, result, x, curve); /* r = x^3 - 3x */ + uECC_vli_modAdd(result, result, curve->b, curve->p, curve->num_words); /* r = x^3 - 3x + b */ } #if uECC_SUPPORTS_secp160r1 @@ -176,22 +176,22 @@ static void vli_mmod_fast_secp160r1(uECC_word_t *result, uECC_word_t *product) { uECC_word_t tmp[2 * num_words_secp160r1]; uECC_word_t copy; - vli_clear(tmp, num_words_secp160r1); - vli_clear(tmp + num_words_secp160r1, num_words_secp160r1); + uECC_vli_clear(tmp, num_words_secp160r1); + uECC_vli_clear(tmp + num_words_secp160r1, num_words_secp160r1); omega_mult_secp160r1(tmp, product + num_words_secp160r1 - 1); /* (Rq, q) = q * c */ product[num_words_secp160r1 - 1] &= 0xffffffff; copy = tmp[num_words_secp160r1 - 1]; tmp[num_words_secp160r1 - 1] &= 0xffffffff; - vli_add(result, product, tmp, num_words_secp160r1); /* (C, r) = r + q */ - vli_clear(product, num_words_secp160r1); + uECC_vli_add(result, product, tmp, num_words_secp160r1); /* (C, r) = r + q */ + uECC_vli_clear(product, num_words_secp160r1); tmp[num_words_secp160r1 - 1] = copy; omega_mult_secp160r1(product, tmp + num_words_secp160r1 - 1); /* Rq*c */ - vli_add(result, result, product, num_words_secp160r1); /* (C1, r) = r + Rq*c */ + uECC_vli_add(result, result, product, num_words_secp160r1); /* (C1, r) = r + Rq*c */ - while (vli_cmp(result, curve_secp160r1.p, num_words_secp160r1) > 0) { - vli_sub(result, result, curve_secp160r1.p, num_words_secp160r1); + while (uECC_vli_cmp(result, curve_secp160r1.p, num_words_secp160r1) > 0) { + uECC_vli_sub(result, result, curve_secp160r1.p, num_words_secp160r1); } } @@ -213,22 +213,22 @@ static void vli_mmod_fast_secp160r1(uECC_word_t *result, uECC_word_t *product) { uECC_word_t tmp[2 * num_words_secp160r1]; uECC_word_t carry; - vli_clear(tmp, num_words_secp160r1); - vli_clear(tmp + num_words_secp160r1, num_words_secp160r1); + uECC_vli_clear(tmp, num_words_secp160r1); + uECC_vli_clear(tmp + num_words_secp160r1, num_words_secp160r1); omega_mult_secp160r1(tmp, product + num_words_secp160r1); /* (Rq, q) = q * c */ - carry = vli_add(result, product, tmp, num_words_secp160r1); /* (C, r) = r + q */ - vli_clear(product, num_words_secp160r1); + carry = uECC_vli_add(result, product, tmp, num_words_secp160r1); /* (C, r) = r + q */ + uECC_vli_clear(product, num_words_secp160r1); omega_mult_secp160r1(product, tmp + num_words_secp160r1); /* Rq*c */ - carry += vli_add(result, result, product, num_words_secp160r1); /* (C1, r) = r + Rq*c */ + carry += uECC_vli_add(result, result, product, num_words_secp160r1); /* (C1, r) = r + Rq*c */ while (carry > 0) { --carry; - vli_sub(result, result, curve_secp160r1.p, num_words_secp160r1); + uECC_vli_sub(result, result, curve_secp160r1.p, num_words_secp160r1); } - if (vli_cmp(result, curve_secp160r1.p, num_words_secp160r1) > 0) { - vli_sub(result, result, curve_secp160r1.p, num_words_secp160r1); + if (uECC_vli_cmp(result, curve_secp160r1.p, num_words_secp160r1) > 0) { + uECC_vli_sub(result, result, curve_secp160r1.p, num_words_secp160r1); } } #endif @@ -239,11 +239,11 @@ static void omega_mult_secp160r1(uint8_t *result, const uint8_t *right) { uint8_t i; /* Multiply by (2^31 + 1). */ - vli_set(result + 4, right, num_words_secp160r1); /* 2^32 */ - vli_rshift1(result + 4, num_words_secp160r1); /* 2^31 */ + uECC_vli_set(result + 4, right, num_words_secp160r1); /* 2^32 */ + uECC_vli_rshift1(result + 4, num_words_secp160r1); /* 2^31 */ result[3] = right[0] << 7; /* get last bit from shift */ - carry = vli_add(result, result, right, num_words_secp160r1); /* 2^31 + 1 */ + carry = uECC_vli_add(result, result, right, num_words_secp160r1); /* 2^31 + 1 */ for (i = num_words_secp160r1; carry; ++i) { uint16_t sum = (uint16_t)result[i] + carry; result[i] = (uint8_t)sum; @@ -256,11 +256,11 @@ static void omega_mult_secp160r1(uint32_t *result, const uint32_t *right) { unsigned i; /* Multiply by (2^31 + 1). */ - vli_set(result + 1, right, num_words_secp160r1); /* 2^32 */ - vli_rshift1(result + 1, num_words_secp160r1); /* 2^31 */ + uECC_vli_set(result + 1, right, num_words_secp160r1); /* 2^32 */ + uECC_vli_rshift1(result + 1, num_words_secp160r1); /* 2^31 */ result[0] = right[0] << 31; /* get last bit from shift */ - carry = vli_add(result, result, right, num_words_secp160r1); /* 2^31 + 1 */ + carry = uECC_vli_add(result, result, right, num_words_secp160r1); /* 2^31 + 1 */ for (i = num_words_secp160r1; carry; ++i) { uint64_t sum = (uint64_t)result[i] + carry; result[i] = (uint32_t)sum; @@ -318,17 +318,17 @@ static void vli_mmod_fast_secp192r1(uint8_t *result, uint8_t *product) { uint8_t tmp[num_words_secp192r1]; uint8_t carry; - vli_set(result, product, num_words_secp192r1); + uECC_vli_set(result, product, num_words_secp192r1); - vli_set(tmp, &product[24], num_words_secp192r1); - carry = vli_add(result, result, tmp, num_words_secp192r1); + uECC_vli_set(tmp, &product[24], num_words_secp192r1); + carry = uECC_vli_add(result, result, tmp, num_words_secp192r1); tmp[0] = tmp[1] = tmp[2] = tmp[3] = tmp[4] = tmp[5] = tmp[6] = tmp[7] = 0; tmp[8] = product[24]; tmp[9] = product[25]; tmp[10] = product[26]; tmp[11] = product[27]; tmp[12] = product[28]; tmp[13] = product[29]; tmp[14] = product[30]; tmp[15] = product[31]; tmp[16] = product[32]; tmp[17] = product[33]; tmp[18] = product[34]; tmp[19] = product[35]; tmp[20] = product[36]; tmp[21] = product[37]; tmp[22] = product[38]; tmp[23] = product[39]; - carry += vli_add(result, result, tmp, num_words_secp192r1); + carry += uECC_vli_add(result, result, tmp, num_words_secp192r1); tmp[0] = tmp[8] = product[40]; tmp[1] = tmp[9] = product[41]; @@ -339,10 +339,10 @@ static void vli_mmod_fast_secp192r1(uint8_t *result, uint8_t *product) { tmp[6] = tmp[14] = product[46]; tmp[7] = tmp[15] = product[47]; tmp[16] = tmp[17] = tmp[18] = tmp[19] = tmp[20] = tmp[21] = tmp[22] = tmp[23] = 0; - carry += vli_add(result, result, tmp, num_words_secp192r1); + carry += uECC_vli_add(result, result, tmp, num_words_secp192r1); - while (carry || vli_cmp(curve_secp192r1.p, result, num_words_secp192r1) != 1) { - carry -= vli_sub(result, result, curve_secp192r1.p, num_words_secp192r1); + while (carry || uECC_vli_cmp(curve_secp192r1.p, result, num_words_secp192r1) != 1) { + carry -= uECC_vli_sub(result, result, curve_secp192r1.p, num_words_secp192r1); } } #elif uECC_WORD_SIZE == 4 @@ -350,25 +350,25 @@ static void vli_mmod_fast_secp192r1(uint32_t *result, uint32_t *product) { uint32_t tmp[num_words_secp192r1]; int carry; - vli_set(result, product, num_words_secp192r1); + uECC_vli_set(result, product, num_words_secp192r1); - vli_set(tmp, &product[6], num_words_secp192r1); - carry = vli_add(result, result, tmp, num_words_secp192r1); + uECC_vli_set(tmp, &product[6], num_words_secp192r1); + carry = uECC_vli_add(result, result, tmp, num_words_secp192r1); tmp[0] = tmp[1] = 0; tmp[2] = product[6]; tmp[3] = product[7]; tmp[4] = product[8]; tmp[5] = product[9]; - carry += vli_add(result, result, tmp, num_words_secp192r1); + carry += uECC_vli_add(result, result, tmp, num_words_secp192r1); tmp[0] = tmp[2] = product[10]; tmp[1] = tmp[3] = product[11]; tmp[4] = tmp[5] = 0; - carry += vli_add(result, result, tmp, num_words_secp192r1); + carry += uECC_vli_add(result, result, tmp, num_words_secp192r1); - while (carry || vli_cmp(curve_secp192r1.p, result, num_words_secp192r1) != 1) { - carry -= vli_sub(result, result, curve_secp192r1.p, num_words_secp192r1); + while (carry || uECC_vli_cmp(curve_secp192r1.p, result, num_words_secp192r1) != 1) { + carry -= uECC_vli_sub(result, result, curve_secp192r1.p, num_words_secp192r1); } } #else @@ -376,22 +376,22 @@ static void vli_mmod_fast_secp192r1(uint64_t *result, uint64_t *product) { uint64_t tmp[num_words_secp192r1]; int carry; - vli_set(result, product, num_words_secp192r1); + uECC_vli_set(result, product, num_words_secp192r1); - vli_set(tmp, &product[3], num_words_secp192r1); - carry = vli_add(result, result, tmp, num_words_secp192r1); + uECC_vli_set(tmp, &product[3], num_words_secp192r1); + carry = uECC_vli_add(result, result, tmp, num_words_secp192r1); tmp[0] = 0; tmp[1] = product[3]; tmp[2] = product[4]; - carry += vli_add(result, result, tmp, num_words_secp192r1); + carry += uECC_vli_add(result, result, tmp, num_words_secp192r1); tmp[0] = tmp[1] = product[5]; tmp[2] = 0; - carry += vli_add(result, result, tmp, num_words_secp192r1); + carry += uECC_vli_add(result, result, tmp, num_words_secp192r1); - while (carry || vli_cmp(curve_secp192r1.p, result, num_words_secp192r1) != 1) { - carry -= vli_sub(result, result, curve_secp192r1.p, num_words_secp192r1); + while (carry || uECC_vli_cmp(curve_secp192r1.p, result, num_words_secp192r1) != 1) { + carry -= uECC_vli_sub(result, result, curve_secp192r1.p, num_words_secp192r1); } } #endif /* uECC_WORD_SIZE */ @@ -456,13 +456,13 @@ static void mod_sqrt_secp224r1_rs(uECC_word_t *d1, const uECC_word_t *f0) { uECC_word_t t[num_words_secp224r1]; - vli_modSquare_fast(t, d0, &curve_secp224r1); /* t <-- d0 ^ 2 */ - vli_modMult_fast(e1, d0, e0, &curve_secp224r1); /* e1 <-- d0 * e0 */ - vli_modAdd(d1, t, f0, curve_secp224r1.p, num_words_secp224r1); /* d1 <-- t + f0 */ - vli_modAdd(e1, e1, e1, curve_secp224r1.p, num_words_secp224r1); /* e1 <-- e1 + e1 */ - vli_modMult_fast(f1, t, f0, &curve_secp224r1); /* f1 <-- t * f0 */ - vli_modAdd(f1, f1, f1, curve_secp224r1.p, num_words_secp224r1); /* f1 <-- f1 + f1 */ - vli_modAdd(f1, f1, f1, curve_secp224r1.p, num_words_secp224r1); /* f1 <-- f1 + f1 */ + uECC_vli_modSquare_fast(t, d0, &curve_secp224r1); /* t <-- d0 ^ 2 */ + uECC_vli_modMult_fast(e1, d0, e0, &curve_secp224r1); /* e1 <-- d0 * e0 */ + uECC_vli_modAdd(d1, t, f0, curve_secp224r1.p, num_words_secp224r1); /* d1 <-- t + f0 */ + uECC_vli_modAdd(e1, e1, e1, curve_secp224r1.p, num_words_secp224r1); /* e1 <-- e1 + e1 */ + uECC_vli_modMult_fast(f1, t, f0, &curve_secp224r1); /* f1 <-- t * f0 */ + uECC_vli_modAdd(f1, f1, f1, curve_secp224r1.p, num_words_secp224r1); /* f1 <-- f1 + f1 */ + uECC_vli_modAdd(f1, f1, f1, curve_secp224r1.p, num_words_secp224r1); /* f1 <-- f1 + f1 */ } /* Routine 3.2.5 RSS; from http://www.nsa.gov/ia/_files/nist-routines.pdf */ @@ -475,9 +475,9 @@ static void mod_sqrt_secp224r1_rss(uECC_word_t *d1, const bitcount_t j) { bitcount_t i; - vli_set(d1, d0, num_words_secp224r1); /* d1 <-- d0 */ - vli_set(e1, e0, num_words_secp224r1); /* e1 <-- e0 */ - vli_set(f1, f0, num_words_secp224r1); /* f1 <-- f0 */ + uECC_vli_set(d1, d0, num_words_secp224r1); /* d1 <-- d0 */ + uECC_vli_set(e1, e0, num_words_secp224r1); /* e1 <-- e0 */ + uECC_vli_set(f1, f0, num_words_secp224r1); /* f1 <-- f0 */ for (i = 1; i <= j; i++) { mod_sqrt_secp224r1_rs(d1, e1, f1, d1, e1, f1); /* RS (d1,e1,f1,d1,e1,f1) */ } @@ -495,20 +495,20 @@ static void mod_sqrt_secp224r1_rm(uECC_word_t *d2, uECC_word_t t1[num_words_secp224r1]; uECC_word_t t2[num_words_secp224r1]; - vli_modMult_fast(t1, e0, e1, &curve_secp224r1); /* t1 <-- e0 * e1 */ - vli_modMult_fast(t1, t1, c, &curve_secp224r1); /* t1 <-- t1 * c */ + uECC_vli_modMult_fast(t1, e0, e1, &curve_secp224r1); /* t1 <-- e0 * e1 */ + uECC_vli_modMult_fast(t1, t1, c, &curve_secp224r1); /* t1 <-- t1 * c */ /* t1 <-- p - t1 */ - vli_modSub(t1, curve_secp224r1.p, t1, curve_secp224r1.p, num_words_secp224r1); - vli_modMult_fast(t2, d0, d1, &curve_secp224r1); /* t2 <-- d0 * d1 */ - vli_modAdd(t2, t2, t1, curve_secp224r1.p, num_words_secp224r1); /* t2 <-- t2 + t1 */ - vli_modMult_fast(t1, d0, e1, &curve_secp224r1); /* t1 <-- d0 * e1 */ - vli_modMult_fast(e2, d1, e0, &curve_secp224r1); /* e2 <-- d1 * e0 */ - vli_modAdd(e2, e2, t1, curve_secp224r1.p, num_words_secp224r1); /* e2 <-- e2 + t1 */ - vli_modSquare_fast(f2, e2, &curve_secp224r1); /* f2 <-- e2^2 */ - vli_modMult_fast(f2, f2, c, &curve_secp224r1); /* f2 <-- f2 * c */ + uECC_vli_modSub(t1, curve_secp224r1.p, t1, curve_secp224r1.p, num_words_secp224r1); + uECC_vli_modMult_fast(t2, d0, d1, &curve_secp224r1); /* t2 <-- d0 * d1 */ + uECC_vli_modAdd(t2, t2, t1, curve_secp224r1.p, num_words_secp224r1); /* t2 <-- t2 + t1 */ + uECC_vli_modMult_fast(t1, d0, e1, &curve_secp224r1); /* t1 <-- d0 * e1 */ + uECC_vli_modMult_fast(e2, d1, e0, &curve_secp224r1); /* e2 <-- d1 * e0 */ + uECC_vli_modAdd(e2, e2, t1, curve_secp224r1.p, num_words_secp224r1); /* e2 <-- e2 + t1 */ + uECC_vli_modSquare_fast(f2, e2, &curve_secp224r1); /* f2 <-- e2^2 */ + uECC_vli_modMult_fast(f2, f2, c, &curve_secp224r1); /* f2 <-- f2 * c */ /* f2 <-- p - f2 */ - vli_modSub(f2, curve_secp224r1.p, f2, curve_secp224r1.p, num_words_secp224r1); - vli_set(d2, t2, num_words_secp224r1); /* d2 <-- t2 */ + uECC_vli_modSub(f2, curve_secp224r1.p, f2, curve_secp224r1.p, num_words_secp224r1); + uECC_vli_set(d2, t2, num_words_secp224r1); /* d2 <-- t2 */ } /* Routine 3.2.7 RP; from http://www.nsa.gov/ia/_files/nist-routines.pdf */ @@ -523,15 +523,15 @@ static void mod_sqrt_secp224r1_rp(uECC_word_t *d1, uECC_word_t e0[num_words_secp224r1] = {1}; /* e0 <-- 1 */ uECC_word_t f0[num_words_secp224r1]; - vli_set(d0, r, num_words_secp224r1); /* d0 <-- r */ + uECC_vli_set(d0, r, num_words_secp224r1); /* d0 <-- r */ /* f0 <-- p - c */ - vli_modSub(f0, curve_secp224r1.p, c, curve_secp224r1.p, num_words_secp224r1); + uECC_vli_modSub(f0, curve_secp224r1.p, c, curve_secp224r1.p, num_words_secp224r1); for (i = 0; i <= 6; i++) { mod_sqrt_secp224r1_rss(d1, e1, f1, d0, e0, f0, pow2i); /* RSS (d1,e1,f1,d0,e0,f0,2^i) */ mod_sqrt_secp224r1_rm(d1, e1, f1, c, d1, e1, d0, e0); /* RM (d1,e1,f1,c,d1,e1,d0,e0) */ - vli_set(d0, d1, num_words_secp224r1); /* d0 <-- d1 */ - vli_set(e0, e1, num_words_secp224r1); /* e0 <-- e1 */ - vli_set(f0, f1, num_words_secp224r1); /* f0 <-- f1 */ + uECC_vli_set(d0, d1, num_words_secp224r1); /* d0 <-- d1 */ + uECC_vli_set(e0, e1, num_words_secp224r1); /* e0 <-- e1 */ + uECC_vli_set(f0, f1, num_words_secp224r1); /* f0 <-- f1 */ pow2i *= 2; } } @@ -551,16 +551,16 @@ static void mod_sqrt_secp224r1(uECC_word_t *a, uECC_Curve curve) { mod_sqrt_secp224r1_rp(d0, e0, f0, a, a); /* RP (d0, e0, f0, c, s) */ mod_sqrt_secp224r1_rs(d1, e1, f1, d0, e0, f0); /* RS (d1, e1, f1, d0, e0, f0) */ for (i = 1; i <= 95; i++) { - vli_set(d0, d1, num_words_secp224r1); /* d0 <-- d1 */ - vli_set(e0, e1, num_words_secp224r1); /* e0 <-- e1 */ - vli_set(f0, f1, num_words_secp224r1); /* f0 <-- f1 */ + uECC_vli_set(d0, d1, num_words_secp224r1); /* d0 <-- d1 */ + uECC_vli_set(e0, e1, num_words_secp224r1); /* e0 <-- e1 */ + uECC_vli_set(f0, f1, num_words_secp224r1); /* f0 <-- f1 */ mod_sqrt_secp224r1_rs(d1, e1, f1, d0, e0, f0); /* RS (d1, e1, f1, d0, e0, f0) */ - if (vli_isZero(d1, num_words_secp224r1)) { /* if d1 == 0 */ + if (uECC_vli_isZero(d1, num_words_secp224r1)) { /* if d1 == 0 */ break; } } - vli_modInv(f1, e0, curve_secp224r1.p, num_words_secp224r1); /* f1 <-- 1 / e0 */ - vli_modMult_fast(a, d0, f1, &curve_secp224r1); /* a <-- d0 / e0 */ + uECC_vli_modInv(f1, e0, curve_secp224r1.p, num_words_secp224r1); /* f1 <-- 1 / e0 */ + uECC_vli_modMult_fast(a, d0, f1, &curve_secp224r1); /* a <-- d0 / e0 */ } #endif /* uECC_SUPPORT_COMPRESSED_POINT */ @@ -573,7 +573,7 @@ static void vli_mmod_fast_secp224r1(uint8_t *result, uint8_t *product) { int8_t carry; /* t */ - vli_set(result, product, num_words_secp224r1); + uECC_vli_set(result, product, num_words_secp224r1); /* s1 */ tmp[0] = tmp[1] = tmp[2] = tmp[3] = 0; @@ -583,14 +583,14 @@ static void vli_mmod_fast_secp224r1(uint8_t *result, uint8_t *product) { tmp[16] = product[32]; tmp[17] = product[33]; tmp[18] = product[34]; tmp[19] = product[35]; tmp[20] = product[36]; tmp[21] = product[37]; tmp[22] = product[38]; tmp[23] = product[39]; tmp[24] = product[40]; tmp[25] = product[41]; tmp[26] = product[42]; tmp[27] = product[43]; - carry = vli_add(result, result, tmp, num_words_secp224r1); + carry = uECC_vli_add(result, result, tmp, num_words_secp224r1); /* s2 */ tmp[12] = product[44]; tmp[13] = product[45]; tmp[14] = product[46]; tmp[15] = product[47]; tmp[16] = product[48]; tmp[17] = product[49]; tmp[18] = product[50]; tmp[19] = product[51]; tmp[20] = product[52]; tmp[21] = product[53]; tmp[22] = product[54]; tmp[23] = product[55]; tmp[24] = tmp[25] = tmp[26] = tmp[27] = 0; - carry += vli_add(result, result, tmp, num_words_secp224r1); + carry += uECC_vli_add(result, result, tmp, num_words_secp224r1); /* d1 */ tmp[0] = product[28]; tmp[1] = product[29]; tmp[2] = product[30]; tmp[3] = product[31]; @@ -600,7 +600,7 @@ static void vli_mmod_fast_secp224r1(uint8_t *result, uint8_t *product) { tmp[16] = product[44]; tmp[17] = product[45]; tmp[18] = product[46]; tmp[19] = product[47]; tmp[20] = product[48]; tmp[21] = product[49]; tmp[22] = product[50]; tmp[23] = product[51]; tmp[24] = product[52]; tmp[25] = product[53]; tmp[26] = product[54]; tmp[27] = product[55]; - carry -= vli_sub(result, result, tmp, num_words_secp224r1); + carry -= uECC_vli_sub(result, result, tmp, num_words_secp224r1); /* d2 */ tmp[0] = product[44]; tmp[1] = product[45]; tmp[2] = product[46]; tmp[3] = product[47]; @@ -610,15 +610,15 @@ static void vli_mmod_fast_secp224r1(uint8_t *result, uint8_t *product) { tmp[16] = tmp[17] = tmp[18] = tmp[19] = 0; tmp[20] = tmp[21] = tmp[22] = tmp[23] = 0; tmp[24] = tmp[25] = tmp[26] = tmp[27] = 0; - carry -= vli_sub(result, result, tmp, num_words_secp224r1); + carry -= uECC_vli_sub(result, result, tmp, num_words_secp224r1); if (carry < 0) { do { - carry += vli_add(result, result, curve_secp224r1.p, num_words_secp224r1); + carry += uECC_vli_add(result, result, curve_secp224r1.p, num_words_secp224r1); } while (carry < 0); } else { - while (carry || vli_cmp(curve_secp224r1.p, result, num_words_secp224r1) != 1) { - carry -= vli_sub(result, result, curve_secp224r1.p, num_words_secp224r1); + while (carry || uECC_vli_cmp(curve_secp224r1.p, result, num_words_secp224r1) != 1) { + carry -= uECC_vli_sub(result, result, curve_secp224r1.p, num_words_secp224r1); } } } @@ -629,7 +629,7 @@ static void vli_mmod_fast_secp224r1(uint32_t *result, uint32_t *product) int carry; /* t */ - vli_set(result, product, num_words_secp224r1); + uECC_vli_set(result, product, num_words_secp224r1); /* s1 */ tmp[0] = tmp[1] = tmp[2] = 0; @@ -637,14 +637,14 @@ static void vli_mmod_fast_secp224r1(uint32_t *result, uint32_t *product) tmp[4] = product[8]; tmp[5] = product[9]; tmp[6] = product[10]; - carry = vli_add(result, result, tmp, num_words_secp224r1); + carry = uECC_vli_add(result, result, tmp, num_words_secp224r1); /* s2 */ tmp[3] = product[11]; tmp[4] = product[12]; tmp[5] = product[13]; tmp[6] = 0; - carry += vli_add(result, result, tmp, num_words_secp224r1); + carry += uECC_vli_add(result, result, tmp, num_words_secp224r1); /* d1 */ tmp[0] = product[7]; @@ -654,22 +654,22 @@ static void vli_mmod_fast_secp224r1(uint32_t *result, uint32_t *product) tmp[4] = product[11]; tmp[5] = product[12]; tmp[6] = product[13]; - carry -= vli_sub(result, result, tmp, num_words_secp224r1); + carry -= uECC_vli_sub(result, result, tmp, num_words_secp224r1); /* d2 */ tmp[0] = product[11]; tmp[1] = product[12]; tmp[2] = product[13]; tmp[3] = tmp[4] = tmp[5] = tmp[6] = 0; - carry -= vli_sub(result, result, tmp, num_words_secp224r1); + carry -= uECC_vli_sub(result, result, tmp, num_words_secp224r1); if (carry < 0) { do { - carry += vli_add(result, result, curve_secp224r1.p, num_words_secp224r1); + carry += uECC_vli_add(result, result, curve_secp224r1.p, num_words_secp224r1); } while (carry < 0); } else { - while (carry || vli_cmp(curve_secp224r1.p, result, num_words_secp224r1) != 1) { - carry -= vli_sub(result, result, curve_secp224r1.p, num_words_secp224r1); + while (carry || uECC_vli_cmp(curve_secp224r1.p, result, num_words_secp224r1) != 1) { + carry -= uECC_vli_sub(result, result, curve_secp224r1.p, num_words_secp224r1); } } } @@ -680,7 +680,7 @@ static void vli_mmod_fast_secp224r1(uint64_t *result, uint64_t *product) int carry = 0; /* t */ - vli_set(result, product, num_words_secp224r1); + uECC_vli_set(result, product, num_words_secp224r1); result[num_words_secp224r1 - 1] &= 0xffffffff; /* s1 */ @@ -688,34 +688,34 @@ static void vli_mmod_fast_secp224r1(uint64_t *result, uint64_t *product) tmp[1] = product[3] & 0xffffffff00000000ull; tmp[2] = product[4]; tmp[3] = product[5] & 0xffffffff; - vli_add(result, result, tmp, num_words_secp224r1); + uECC_vli_add(result, result, tmp, num_words_secp224r1); /* s2 */ tmp[1] = product[5] & 0xffffffff00000000ull; tmp[2] = product[6]; tmp[3] = 0; - vli_add(result, result, tmp, num_words_secp224r1); + uECC_vli_add(result, result, tmp, num_words_secp224r1); /* d1 */ tmp[0] = (product[3] >> 32) | (product[4] << 32); tmp[1] = (product[4] >> 32) | (product[5] << 32); tmp[2] = (product[5] >> 32) | (product[6] << 32); tmp[3] = product[6] >> 32; - carry -= vli_sub(result, result, tmp, num_words_secp224r1); + carry -= uECC_vli_sub(result, result, tmp, num_words_secp224r1); /* d2 */ tmp[0] = (product[5] >> 32) | (product[6] << 32); tmp[1] = product[6] >> 32; tmp[2] = tmp[3] = 0; - carry -= vli_sub(result, result, tmp, num_words_secp224r1); + carry -= uECC_vli_sub(result, result, tmp, num_words_secp224r1); if (carry < 0) { do { - carry += vli_add(result, result, curve_secp224r1.p, num_words_secp224r1); + carry += uECC_vli_add(result, result, curve_secp224r1.p, num_words_secp224r1); } while (carry < 0); } else { - while (vli_cmp(curve_secp224r1.p, result, num_words_secp224r1) != 1) { - vli_sub(result, result, curve_secp224r1.p, num_words_secp224r1); + while (uECC_vli_cmp(curve_secp224r1.p, result, num_words_secp224r1) != 1) { + uECC_vli_sub(result, result, curve_secp224r1.p, num_words_secp224r1); } } } @@ -777,7 +777,7 @@ static void vli_mmod_fast_secp256r1(uint8_t *result, uint8_t *product) { int8_t carry; /* t */ - vli_set(result, product, num_words_secp256r1); + uECC_vli_set(result, product, num_words_secp256r1); /* s1 */ tmp[0] = tmp[1] = tmp[2] = tmp[3] = 0; @@ -788,8 +788,8 @@ static void vli_mmod_fast_secp256r1(uint8_t *result, uint8_t *product) { tmp[20] = product[52]; tmp[21] = product[53]; tmp[22] = product[54]; tmp[23] = product[55]; tmp[24] = product[56]; tmp[25] = product[57]; tmp[26] = product[58]; tmp[27] = product[59]; tmp[28] = product[60]; tmp[29] = product[61]; tmp[30] = product[62]; tmp[31] = product[63]; - carry = vli_add(tmp, tmp, tmp, num_words_secp256r1); - carry += vli_add(result, result, tmp, num_words_secp256r1); + carry = uECC_vli_add(tmp, tmp, tmp, num_words_secp256r1); + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); /* s2 */ tmp[12] = product[48]; tmp[13] = product[49]; tmp[14] = product[50]; tmp[15] = product[51]; @@ -797,8 +797,8 @@ static void vli_mmod_fast_secp256r1(uint8_t *result, uint8_t *product) { tmp[20] = product[56]; tmp[21] = product[57]; tmp[22] = product[58]; tmp[23] = product[59]; tmp[24] = product[60]; tmp[25] = product[61]; tmp[26] = product[62]; tmp[27] = product[63]; tmp[28] = tmp[29] = tmp[30] = tmp[31] = 0; - carry += vli_add(tmp, tmp, tmp, num_words_secp256r1); - carry += vli_add(result, result, tmp, num_words_secp256r1); + carry += uECC_vli_add(tmp, tmp, tmp, num_words_secp256r1); + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); /* s3 */ tmp[0] = product[32]; tmp[1] = product[33]; tmp[2] = product[34]; tmp[3] = product[35]; @@ -809,7 +809,7 @@ static void vli_mmod_fast_secp256r1(uint8_t *result, uint8_t *product) { tmp[20] = tmp[21] = tmp[22] = tmp[23] = 0; tmp[24] = product[56]; tmp[25] = product[57]; tmp[26] = product[58]; tmp[27] = product[59]; tmp[28] = product[60]; tmp[29] = product[61]; tmp[30] = product[62]; tmp[31] = product[63]; - carry += vli_add(result, result, tmp, num_words_secp256r1); + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); /* s4 */ tmp[0] = product[36]; tmp[1] = product[37]; tmp[2] = product[38]; tmp[3] = product[39]; @@ -820,7 +820,7 @@ static void vli_mmod_fast_secp256r1(uint8_t *result, uint8_t *product) { tmp[20] = product[60]; tmp[21] = product[61]; tmp[22] = product[62]; tmp[23] = product[63]; tmp[24] = product[52]; tmp[25] = product[53]; tmp[26] = product[54]; tmp[27] = product[55]; tmp[28] = product[32]; tmp[29] = product[33]; tmp[30] = product[34]; tmp[31] = product[35]; - carry += vli_add(result, result, tmp, num_words_secp256r1); + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); /* d1 */ tmp[0] = product[44]; tmp[1] = product[45]; tmp[2] = product[46]; tmp[3] = product[47]; @@ -831,7 +831,7 @@ static void vli_mmod_fast_secp256r1(uint8_t *result, uint8_t *product) { tmp[20] = tmp[21] = tmp[22] = tmp[23] = 0; tmp[24] = product[32]; tmp[25] = product[33]; tmp[26] = product[34]; tmp[27] = product[35]; tmp[28] = product[40]; tmp[29] = product[41]; tmp[30] = product[42]; tmp[31] = product[43]; - carry -= vli_sub(result, result, tmp, num_words_secp256r1); + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); /* d2 */ tmp[0] = product[48]; tmp[1] = product[49]; tmp[2] = product[50]; tmp[3] = product[51]; @@ -842,7 +842,7 @@ static void vli_mmod_fast_secp256r1(uint8_t *result, uint8_t *product) { tmp[20] = tmp[21] = tmp[22] = tmp[23] = 0; tmp[24] = product[36]; tmp[25] = product[37]; tmp[26] = product[38]; tmp[27] = product[39]; tmp[28] = product[44]; tmp[29] = product[45]; tmp[30] = product[46]; tmp[31] = product[47]; - carry -= vli_sub(result, result, tmp, num_words_secp256r1); + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); /* d3 */ tmp[0] = product[52]; tmp[1] = product[53]; tmp[2] = product[54]; tmp[3] = product[55]; @@ -853,7 +853,7 @@ static void vli_mmod_fast_secp256r1(uint8_t *result, uint8_t *product) { tmp[20] = product[40]; tmp[21] = product[41]; tmp[22] = product[42]; tmp[23] = product[43]; tmp[24] = tmp[25] = tmp[26] = tmp[27] = 0; tmp[28] = product[48]; tmp[29] = product[49]; tmp[30] = product[50]; tmp[31] = product[51]; - carry -= vli_sub(result, result, tmp, num_words_secp256r1); + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); /* d4 */ tmp[0] = product[56]; tmp[1] = product[57]; tmp[2] = product[58]; tmp[3] = product[59]; @@ -864,15 +864,15 @@ static void vli_mmod_fast_secp256r1(uint8_t *result, uint8_t *product) { tmp[20] = product[44]; tmp[21] = product[45]; tmp[22] = product[46]; tmp[23] = product[47]; tmp[24] = tmp[25] = tmp[26] = tmp[27] = 0; tmp[28] = product[52]; tmp[29] = product[53]; tmp[30] = product[54]; tmp[31] = product[55]; - carry -= vli_sub(result, result, tmp, num_words_secp256r1); + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); if (carry < 0) { do { - carry += vli_add(result, result, curve_secp256r1.p, num_words_secp256r1); + carry += uECC_vli_add(result, result, curve_secp256r1.p, num_words_secp256r1); } while (carry < 0); } else { - while (carry || vli_cmp(curve_secp256r1.p, result, num_words_secp256r1) != 1) { - carry -= vli_sub(result, result, curve_secp256r1.p, num_words_secp256r1); + while (carry || uECC_vli_cmp(curve_secp256r1.p, result, num_words_secp256r1) != 1) { + carry -= uECC_vli_sub(result, result, curve_secp256r1.p, num_words_secp256r1); } } } @@ -882,7 +882,7 @@ static void vli_mmod_fast_secp256r1(uint32_t *result, uint32_t *product) { int carry; /* t */ - vli_set(result, product, num_words_secp256r1); + uECC_vli_set(result, product, num_words_secp256r1); /* s1 */ tmp[0] = tmp[1] = tmp[2] = 0; @@ -891,8 +891,8 @@ static void vli_mmod_fast_secp256r1(uint32_t *result, uint32_t *product) { tmp[5] = product[13]; tmp[6] = product[14]; tmp[7] = product[15]; - carry = vli_add(tmp, tmp, tmp, num_words_secp256r1); - carry += vli_add(result, result, tmp, num_words_secp256r1); + carry = uECC_vli_add(tmp, tmp, tmp, num_words_secp256r1); + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); /* s2 */ tmp[3] = product[12]; @@ -900,8 +900,8 @@ static void vli_mmod_fast_secp256r1(uint32_t *result, uint32_t *product) { tmp[5] = product[14]; tmp[6] = product[15]; tmp[7] = 0; - carry += vli_add(tmp, tmp, tmp, num_words_secp256r1); - carry += vli_add(result, result, tmp, num_words_secp256r1); + carry += uECC_vli_add(tmp, tmp, tmp, num_words_secp256r1); + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); /* s3 */ tmp[0] = product[8]; @@ -910,7 +910,7 @@ static void vli_mmod_fast_secp256r1(uint32_t *result, uint32_t *product) { tmp[3] = tmp[4] = tmp[5] = 0; tmp[6] = product[14]; tmp[7] = product[15]; - carry += vli_add(result, result, tmp, num_words_secp256r1); + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); /* s4 */ tmp[0] = product[9]; @@ -921,7 +921,7 @@ static void vli_mmod_fast_secp256r1(uint32_t *result, uint32_t *product) { tmp[5] = product[15]; tmp[6] = product[13]; tmp[7] = product[8]; - carry += vli_add(result, result, tmp, num_words_secp256r1); + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); /* d1 */ tmp[0] = product[11]; @@ -930,7 +930,7 @@ static void vli_mmod_fast_secp256r1(uint32_t *result, uint32_t *product) { tmp[3] = tmp[4] = tmp[5] = 0; tmp[6] = product[8]; tmp[7] = product[10]; - carry -= vli_sub(result, result, tmp, num_words_secp256r1); + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); /* d2 */ tmp[0] = product[12]; @@ -940,7 +940,7 @@ static void vli_mmod_fast_secp256r1(uint32_t *result, uint32_t *product) { tmp[4] = tmp[5] = 0; tmp[6] = product[9]; tmp[7] = product[11]; - carry -= vli_sub(result, result, tmp, num_words_secp256r1); + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); /* d3 */ tmp[0] = product[13]; @@ -951,7 +951,7 @@ static void vli_mmod_fast_secp256r1(uint32_t *result, uint32_t *product) { tmp[5] = product[10]; tmp[6] = 0; tmp[7] = product[12]; - carry -= vli_sub(result, result, tmp, num_words_secp256r1); + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); /* d4 */ tmp[0] = product[14]; @@ -962,15 +962,15 @@ static void vli_mmod_fast_secp256r1(uint32_t *result, uint32_t *product) { tmp[5] = product[11]; tmp[6] = 0; tmp[7] = product[13]; - carry -= vli_sub(result, result, tmp, num_words_secp256r1); + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); if (carry < 0) { do { - carry += vli_add(result, result, curve_secp256r1.p, num_words_secp256r1); + carry += uECC_vli_add(result, result, curve_secp256r1.p, num_words_secp256r1); } while (carry < 0); } else { - while (carry || vli_cmp(curve_secp256r1.p, result, num_words_secp256r1) != 1) { - carry -= vli_sub(result, result, curve_secp256r1.p, num_words_secp256r1); + while (carry || uECC_vli_cmp(curve_secp256r1.p, result, num_words_secp256r1) != 1) { + carry -= uECC_vli_sub(result, result, curve_secp256r1.p, num_words_secp256r1); } } } @@ -980,72 +980,72 @@ static void vli_mmod_fast_secp256r1(uint64_t *result, uint64_t *product) { int carry; /* t */ - vli_set(result, product, num_words_secp256r1); + uECC_vli_set(result, product, num_words_secp256r1); /* s1 */ tmp[0] = 0; tmp[1] = product[5] & 0xffffffff00000000ull; tmp[2] = product[6]; tmp[3] = product[7]; - carry = vli_add(tmp, tmp, tmp, num_words_secp256r1); - carry += vli_add(result, result, tmp, num_words_secp256r1); + carry = uECC_vli_add(tmp, tmp, tmp, num_words_secp256r1); + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); /* s2 */ tmp[1] = product[6] << 32; tmp[2] = (product[6] >> 32) | (product[7] << 32); tmp[3] = product[7] >> 32; - carry += vli_add(tmp, tmp, tmp, num_words_secp256r1); - carry += vli_add(result, result, tmp, num_words_secp256r1); + carry += uECC_vli_add(tmp, tmp, tmp, num_words_secp256r1); + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); /* s3 */ tmp[0] = product[4]; tmp[1] = product[5] & 0xffffffff; tmp[2] = 0; tmp[3] = product[7]; - carry += vli_add(result, result, tmp, num_words_secp256r1); + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); /* s4 */ tmp[0] = (product[4] >> 32) | (product[5] << 32); tmp[1] = (product[5] >> 32) | (product[6] & 0xffffffff00000000ull); tmp[2] = product[7]; tmp[3] = (product[6] >> 32) | (product[4] << 32); - carry += vli_add(result, result, tmp, num_words_secp256r1); + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); /* d1 */ tmp[0] = (product[5] >> 32) | (product[6] << 32); tmp[1] = (product[6] >> 32); tmp[2] = 0; tmp[3] = (product[4] & 0xffffffff) | (product[5] << 32); - carry -= vli_sub(result, result, tmp, num_words_secp256r1); + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); /* d2 */ tmp[0] = product[6]; tmp[1] = product[7]; tmp[2] = 0; tmp[3] = (product[4] >> 32) | (product[5] & 0xffffffff00000000ull); - carry -= vli_sub(result, result, tmp, num_words_secp256r1); + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); /* d3 */ tmp[0] = (product[6] >> 32) | (product[7] << 32); tmp[1] = (product[7] >> 32) | (product[4] << 32); tmp[2] = (product[4] >> 32) | (product[5] << 32); tmp[3] = (product[6] << 32); - carry -= vli_sub(result, result, tmp, num_words_secp256r1); + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); /* d4 */ tmp[0] = product[7]; tmp[1] = product[4] & 0xffffffff00000000ull; tmp[2] = product[5]; tmp[3] = product[6] & 0xffffffff00000000ull; - carry -= vli_sub(result, result, tmp, num_words_secp256r1); + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); if (carry < 0) { do { - carry += vli_add(result, result, curve_secp256r1.p, num_words_secp256r1); + carry += uECC_vli_add(result, result, curve_secp256r1.p, num_words_secp256r1); } while (carry < 0); } else { - while (carry || vli_cmp(curve_secp256r1.p, result, num_words_secp256r1) != 1) { - carry -= vli_sub(result, result, curve_secp256r1.p, num_words_secp256r1); + while (carry || uECC_vli_cmp(curve_secp256r1.p, result, num_words_secp256r1) != 1) { + carry -= uECC_vli_sub(result, result, curve_secp256r1.p, num_words_secp256r1); } } } @@ -1112,41 +1112,41 @@ static void double_jacobian_secp256k1(uECC_word_t * X1, uECC_word_t t4[num_words_secp256k1]; uECC_word_t t5[num_words_secp256k1]; - if (vli_isZero(Z1, num_words_secp256k1)) { + if (uECC_vli_isZero(Z1, num_words_secp256k1)) { return; } - vli_modSquare_fast(t5, Y1, curve); /* t5 = y1^2 */ - vli_modMult_fast(t4, X1, t5, curve); /* t4 = x1*y1^2 = A */ - vli_modSquare_fast(X1, X1, curve); /* t1 = x1^2 */ - vli_modSquare_fast(t5, t5, curve); /* t5 = y1^4 */ - vli_modMult_fast(Z1, Y1, Z1, curve); /* t3 = y1*z1 = z3 */ + uECC_vli_modSquare_fast(t5, Y1, curve); /* t5 = y1^2 */ + uECC_vli_modMult_fast(t4, X1, t5, curve); /* t4 = x1*y1^2 = A */ + uECC_vli_modSquare_fast(X1, X1, curve); /* t1 = x1^2 */ + uECC_vli_modSquare_fast(t5, t5, curve); /* t5 = y1^4 */ + uECC_vli_modMult_fast(Z1, Y1, Z1, curve); /* t3 = y1*z1 = z3 */ - vli_modAdd(Y1, X1, X1, curve->p, num_words_secp256k1); /* t2 = 2*x1^2 */ - vli_modAdd(Y1, Y1, X1, curve->p, num_words_secp256k1); /* t2 = 3*x1^2 */ - if (vli_testBit(Y1, 0)) { - uECC_word_t carry = vli_add(Y1, Y1, curve->p, num_words_secp256k1); - vli_rshift1(Y1, num_words_secp256k1); + uECC_vli_modAdd(Y1, X1, X1, curve->p, num_words_secp256k1); /* t2 = 2*x1^2 */ + uECC_vli_modAdd(Y1, Y1, X1, curve->p, num_words_secp256k1); /* t2 = 3*x1^2 */ + if (uECC_vli_testBit(Y1, 0)) { + uECC_word_t carry = uECC_vli_add(Y1, Y1, curve->p, num_words_secp256k1); + uECC_vli_rshift1(Y1, num_words_secp256k1); Y1[num_words_secp256k1 - 1] |= carry << (uECC_WORD_BITS - 1); } else { - vli_rshift1(Y1, num_words_secp256k1); + uECC_vli_rshift1(Y1, num_words_secp256k1); } /* t2 = 3/2*(x1^2) = B */ - vli_modSquare_fast(X1, Y1, curve); /* t1 = B^2 */ - vli_modSub(X1, X1, t4, curve->p, num_words_secp256k1); /* t1 = B^2 - A */ - vli_modSub(X1, X1, t4, curve->p, num_words_secp256k1); /* t1 = B^2 - 2A = x3 */ + uECC_vli_modSquare_fast(X1, Y1, curve); /* t1 = B^2 */ + uECC_vli_modSub(X1, X1, t4, curve->p, num_words_secp256k1); /* t1 = B^2 - A */ + uECC_vli_modSub(X1, X1, t4, curve->p, num_words_secp256k1); /* t1 = B^2 - 2A = x3 */ - vli_modSub(t4, t4, X1, curve->p, num_words_secp256k1); /* t4 = A - x3 */ - vli_modMult_fast(Y1, Y1, t4, curve); /* t2 = B * (A - x3) */ - vli_modSub(Y1, Y1, t5, curve->p, num_words_secp256k1); /* t2 = B * (A - x3) - y1^4 = y3 */ + uECC_vli_modSub(t4, t4, X1, curve->p, num_words_secp256k1); /* t4 = A - x3 */ + uECC_vli_modMult_fast(Y1, Y1, t4, curve); /* t2 = B * (A - x3) */ + uECC_vli_modSub(Y1, Y1, t5, curve->p, num_words_secp256k1); /* t2 = B * (A - x3) - y1^4 = y3 */ } /* Computes result = x^3 + b. result must not overlap x. */ static void x_side_secp256k1(uECC_word_t *result, const uECC_word_t *x, uECC_Curve curve) { - vli_modSquare_fast(result, x, curve); /* r = x^2 */ - vli_modMult_fast(result, result, x, curve); /* r = x^3 */ - vli_modAdd(result, result, curve->b, curve->p, num_words_secp256k1); /* r = x^3 + b */ + uECC_vli_modSquare_fast(result, x, curve); /* r = x^2 */ + uECC_vli_modMult_fast(result, result, x, curve); /* r = x^3 */ + uECC_vli_modAdd(result, result, curve->b, curve->p, num_words_secp256k1); /* r = x^3 + b */ } #if (uECC_OPTIMIZATION_LEVEL > 0) @@ -1155,22 +1155,22 @@ static void vli_mmod_fast_secp256k1(uECC_word_t *result, uECC_word_t *product) { uECC_word_t tmp[2 * num_words_secp256k1]; uECC_word_t carry; - vli_clear(tmp, num_words_secp256k1); - vli_clear(tmp + num_words_secp256k1, num_words_secp256k1); + uECC_vli_clear(tmp, num_words_secp256k1); + uECC_vli_clear(tmp + num_words_secp256k1, num_words_secp256k1); omega_mult_secp256k1(tmp, product + num_words_secp256k1); /* (Rq, q) = q * c */ - carry = vli_add(result, product, tmp, num_words_secp256k1); /* (C, r) = r + q */ - vli_clear(product, num_words_secp256k1); + carry = uECC_vli_add(result, product, tmp, num_words_secp256k1); /* (C, r) = r + q */ + uECC_vli_clear(product, num_words_secp256k1); omega_mult_secp256k1(product, tmp + num_words_secp256k1); /* Rq*c */ - carry += vli_add(result, result, product, num_words_secp256k1); /* (C1, r) = r + Rq*c */ + carry += uECC_vli_add(result, result, product, num_words_secp256k1); /* (C1, r) = r + Rq*c */ while (carry > 0) { --carry; - vli_sub(result, result, curve_secp256k1.p, num_words_secp256k1); + uECC_vli_sub(result, result, curve_secp256k1.p, num_words_secp256k1); } - if (vli_cmp(result, curve_secp256k1.p, num_words_secp256k1) > 0) { - vli_sub(result, result, curve_secp256k1.p, num_words_secp256k1); + if (uECC_vli_cmp(result, curve_secp256k1.p, num_words_secp256k1) > 0) { + uECC_vli_sub(result, result, curve_secp256k1.p, num_words_secp256k1); } } @@ -1201,7 +1201,8 @@ static void omega_mult_secp256k1(uint8_t * result, const uint8_t * right) { result[num_words_secp256k1] = r0; result[num_words_secp256k1 + 1] = r1; /* add the 2^32 multiple */ - result[4 + num_words_secp256k1] = vli_add(result + 4, result + 4, right, num_words_secp256k1); + result[4 + num_words_secp256k1] = + uECC_vli_add(result + 4, result + 4, right, num_words_secp256k1); } #elif uECC_WORD_SIZE == 4 static void omega_mult_secp256k1(uint32_t * result, const uint32_t * right) { @@ -1216,7 +1217,8 @@ static void omega_mult_secp256k1(uint32_t * result, const uint32_t * right) { } result[num_words_secp256k1] = carry; /* add the 2^32 multiple */ - result[1 + num_words_secp256k1] = vli_add(result + 1, result + 1, right, num_words_secp256k1); + result[1 + num_words_secp256k1] = + uECC_vli_add(result + 1, result + 1, right, num_words_secp256k1); } #else static void omega_mult_secp256k1(uint64_t * result, const uint64_t * right) { diff --git a/platform-specific.inc b/platform-specific.inc index a7e9404..3eb95cd 100644 --- a/platform-specific.inc +++ b/platform-specific.inc @@ -3,102 +3,7 @@ #ifndef _UECC_PLATFORM_SPECIFIC_H_ #define _UECC_PLATFORM_SPECIFIC_H_ -#ifndef uECC_PLATFORM - #if __AVR__ - #define uECC_PLATFORM uECC_avr - #elif defined(__thumb2__) || defined(_M_ARMT) /* I think MSVC only supports Thumb-2 targets */ - #define uECC_PLATFORM uECC_arm_thumb2 - #elif defined(__thumb__) - #define uECC_PLATFORM uECC_arm_thumb - #elif defined(__arm__) || defined(_M_ARM) - #define uECC_PLATFORM uECC_arm - #elif defined(__aarch64__) - #define uECC_PLATFORM uECC_arm64 - #elif defined(__i386__) || defined(_M_IX86) || defined(_X86_) || defined(__I86__) - #define uECC_PLATFORM uECC_x86 - #elif defined(__amd64__) || defined(_M_X64) - #define uECC_PLATFORM uECC_x86_64 - #else - #define uECC_PLATFORM uECC_arch_other - #endif -#endif - -#ifndef uECC_WORD_SIZE - #if uECC_PLATFORM == uECC_avr - #define uECC_WORD_SIZE 1 - #elif (uECC_PLATFORM == uECC_x86_64 || uECC_PLATFORM == uECC_arm64) - #define uECC_WORD_SIZE 8 - #else - #define uECC_WORD_SIZE 4 - #endif -#endif - -#if (uECC_WORD_SIZE != 1) && (uECC_WORD_SIZE != 4) && (uECC_WORD_SIZE != 8) - #error "Unsupported value for uECC_WORD_SIZE" -#endif - -#if ((uECC_PLATFORM == uECC_avr) && (uECC_WORD_SIZE != 1)) - #pragma message ("uECC_WORD_SIZE must be 1 for AVR") - #undef uECC_WORD_SIZE - #define uECC_WORD_SIZE 1 -#endif - -#if ((uECC_PLATFORM == uECC_arm || uECC_PLATFORM == uECC_arm_thumb || \ - uECC_PLATFORM == uECC_arm_thumb2) && \ - (uECC_WORD_SIZE != 4)) - #pragma message ("uECC_WORD_SIZE must be 4 for ARM") - #undef uECC_WORD_SIZE - #define uECC_WORD_SIZE 4 -#endif - -#if defined(__SIZEOF_INT128__) || ((__clang_major__ * 100 + __clang_minor__) >= 302) - #define SUPPORTS_INT128 1 -#else - #define SUPPORTS_INT128 0 -#endif - -#if (uECC_WORD_SIZE == 1) - -typedef uint8_t uECC_word_t; -typedef uint16_t uECC_dword_t; -typedef int8_t wordcount_t; -typedef int16_t bitcount_t; -typedef int8_t cmpresult_t; - -#define HIGH_BIT_SET 0x80 -#define uECC_WORD_BITS 8 -#define uECC_WORD_BITS_SHIFT 3 -#define uECC_WORD_BITS_MASK 0x07 - -#elif (uECC_WORD_SIZE == 4) - -typedef uint32_t uECC_word_t; -typedef uint64_t uECC_dword_t; -typedef int wordcount_t; -typedef int bitcount_t; -typedef int cmpresult_t; - -#define HIGH_BIT_SET 0x80000000 -#define uECC_WORD_BITS 32 -#define uECC_WORD_BITS_SHIFT 5 -#define uECC_WORD_BITS_MASK 0x01F - -#elif (uECC_WORD_SIZE == 8) - -typedef uint64_t uECC_word_t; -#if SUPPORTS_INT128 -typedef unsigned __int128 uECC_dword_t; -#endif -typedef int wordcount_t; -typedef int bitcount_t; -typedef int cmpresult_t; - -#define HIGH_BIT_SET 0x8000000000000000ull -#define uECC_WORD_BITS 64 -#define uECC_WORD_BITS_SHIFT 6 -#define uECC_WORD_BITS_MASK 0x03F - -#endif /* uECC_WORD_SIZE */ +#include "types.inc" #if (defined(_WIN32) || defined(_WIN64)) /* Windows */ diff --git a/types.inc b/types.inc new file mode 100644 index 0000000..47c9451 --- /dev/null +++ b/types.inc @@ -0,0 +1,103 @@ +/* Copyright 2015, Kenneth MacKay. Licensed under the BSD 2-clause license. */ + +#ifndef _UECC_TYPES_H_ +#define _UECC_TYPES_H_ + +#ifndef uECC_PLATFORM + #if __AVR__ + #define uECC_PLATFORM uECC_avr + #elif defined(__thumb2__) || defined(_M_ARMT) /* I think MSVC only supports Thumb-2 targets */ + #define uECC_PLATFORM uECC_arm_thumb2 + #elif defined(__thumb__) + #define uECC_PLATFORM uECC_arm_thumb + #elif defined(__arm__) || defined(_M_ARM) + #define uECC_PLATFORM uECC_arm + #elif defined(__aarch64__) + #define uECC_PLATFORM uECC_arm64 + #elif defined(__i386__) || defined(_M_IX86) || defined(_X86_) || defined(__I86__) + #define uECC_PLATFORM uECC_x86 + #elif defined(__amd64__) || defined(_M_X64) + #define uECC_PLATFORM uECC_x86_64 + #else + #define uECC_PLATFORM uECC_arch_other + #endif +#endif + +#ifndef uECC_WORD_SIZE + #if uECC_PLATFORM == uECC_avr + #define uECC_WORD_SIZE 1 + #elif (uECC_PLATFORM == uECC_x86_64 || uECC_PLATFORM == uECC_arm64) + #define uECC_WORD_SIZE 8 + #else + #define uECC_WORD_SIZE 4 + #endif +#endif + +#if (uECC_WORD_SIZE != 1) && (uECC_WORD_SIZE != 4) && (uECC_WORD_SIZE != 8) + #error "Unsupported value for uECC_WORD_SIZE" +#endif + +#if ((uECC_PLATFORM == uECC_avr) && (uECC_WORD_SIZE != 1)) + #pragma message ("uECC_WORD_SIZE must be 1 for AVR") + #undef uECC_WORD_SIZE + #define uECC_WORD_SIZE 1 +#endif + +#if ((uECC_PLATFORM == uECC_arm || uECC_PLATFORM == uECC_arm_thumb || \ + uECC_PLATFORM == uECC_arm_thumb2) && \ + (uECC_WORD_SIZE != 4)) + #pragma message ("uECC_WORD_SIZE must be 4 for ARM") + #undef uECC_WORD_SIZE + #define uECC_WORD_SIZE 4 +#endif + +#if defined(__SIZEOF_INT128__) || ((__clang_major__ * 100 + __clang_minor__) >= 302) + #define SUPPORTS_INT128 1 +#else + #define SUPPORTS_INT128 0 +#endif + +#if (uECC_WORD_SIZE == 1) + +typedef uint8_t uECC_word_t; +typedef uint16_t uECC_dword_t; +typedef int8_t wordcount_t; +typedef int16_t bitcount_t; +typedef int8_t cmpresult_t; + +#define HIGH_BIT_SET 0x80 +#define uECC_WORD_BITS 8 +#define uECC_WORD_BITS_SHIFT 3 +#define uECC_WORD_BITS_MASK 0x07 + +#elif (uECC_WORD_SIZE == 4) + +typedef uint32_t uECC_word_t; +typedef uint64_t uECC_dword_t; +typedef int wordcount_t; +typedef int bitcount_t; +typedef int cmpresult_t; + +#define HIGH_BIT_SET 0x80000000 +#define uECC_WORD_BITS 32 +#define uECC_WORD_BITS_SHIFT 5 +#define uECC_WORD_BITS_MASK 0x01F + +#elif (uECC_WORD_SIZE == 8) + +typedef uint64_t uECC_word_t; +#if SUPPORTS_INT128 +typedef unsigned __int128 uECC_dword_t; +#endif +typedef int wordcount_t; +typedef int bitcount_t; +typedef int cmpresult_t; + +#define HIGH_BIT_SET 0x8000000000000000ull +#define uECC_WORD_BITS 64 +#define uECC_WORD_BITS_SHIFT 6 +#define uECC_WORD_BITS_MASK 0x03F + +#endif /* uECC_WORD_SIZE */ + +#endif /* _UECC_TYPES_H_ */ diff --git a/uECC.c b/uECC.c index 534a80e..47192aa 100644 --- a/uECC.c +++ b/uECC.c @@ -20,6 +20,16 @@ #define uECC_MAX_BYTES 32 #endif +#ifndef uECC_ENABLE_VLI_API + #define uECC_ENABLE_VLI_API 0 +#endif + +#if uECC_ENABLE_VLI_API + #define uECC_VLI_API +#else + #define uECC_VLI_API static +#endif + #include "platform-specific.inc" #if (uECC_WORD_SIZE == 1) @@ -66,7 +76,7 @@ void uECC_set_rng(uECC_RNG_Function rng_function) { g_rng_function = rng_function; } -static void vli_clear(uECC_word_t *vli, wordcount_t num_words) { +uECC_VLI_API void uECC_vli_clear(uECC_word_t *vli, wordcount_t num_words) { wordcount_t i; for (i = 0; i < num_words; ++i) { vli[i] = 0; @@ -75,7 +85,7 @@ static void vli_clear(uECC_word_t *vli, wordcount_t num_words) { /* Constant-time comparison to zero - secure way to compare long integers */ /* Returns 1 if vli == 0, 0 otherwise. */ -static uECC_word_t vli_isZero(const uECC_word_t *vli, wordcount_t num_words) { +uECC_VLI_API uECC_word_t uECC_vli_isZero(const uECC_word_t *vli, wordcount_t num_words) { uECC_word_t bits = 0; wordcount_t i; for (i = 0; i < num_words; ++i) { @@ -85,7 +95,7 @@ static uECC_word_t vli_isZero(const uECC_word_t *vli, wordcount_t num_words) { } /* Returns nonzero if bit 'bit' of vli is set. */ -static uECC_word_t vli_testBit(const uECC_word_t *vli, bitcount_t bit) { +uECC_VLI_API uECC_word_t uECC_vli_testBit(const uECC_word_t *vli, bitcount_t bit) { return (vli[bit >> uECC_WORD_BITS_SHIFT] & ((uECC_word_t)1 << (bit & uECC_WORD_BITS_MASK))); } @@ -101,7 +111,7 @@ static wordcount_t vli_numDigits(const uECC_word_t *vli, const wordcount_t max_w } /* Counts the number of bits required to represent vli. */ -static bitcount_t vli_numBits(const uECC_word_t *vli, const wordcount_t max_words) { +uECC_VLI_API bitcount_t uECC_vli_numBits(const uECC_word_t *vli, const wordcount_t max_words) { uECC_word_t i; uECC_word_t digit; @@ -119,7 +129,7 @@ static bitcount_t vli_numBits(const uECC_word_t *vli, const wordcount_t max_word } /* Sets dest = src. */ -static void vli_set(uECC_word_t *dest, const uECC_word_t *src, wordcount_t num_words) { +uECC_VLI_API void uECC_vli_set(uECC_word_t *dest, const uECC_word_t *src, wordcount_t num_words) { wordcount_t i; for (i = 0; i < num_words; ++i) { dest[i] = src[i]; @@ -127,9 +137,9 @@ static void vli_set(uECC_word_t *dest, const uECC_word_t *src, wordcount_t num_w } /* Returns sign of left - right. */ -static cmpresult_t vli_cmp(const uECC_word_t *left, - const uECC_word_t *right, - wordcount_t num_words) { +uECC_VLI_API cmpresult_t uECC_vli_cmp(const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words) { wordcount_t i; for (i = num_words - 1; i >= 0; --i) { if (left[i] > right[i]) { @@ -143,9 +153,9 @@ static cmpresult_t vli_cmp(const uECC_word_t *left, /* Constant-time comparison function - secure way to compare long integers */ /* Returns one if left == right, zero otherwise */ -static uECC_word_t vli_equal(const uECC_word_t *left, - const uECC_word_t *right, - wordcount_t num_words) { +uECC_VLI_API uECC_word_t uECC_vli_equal(const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words) { uECC_word_t diff = 0; wordcount_t i; for (i = num_words - 1; i >= 0; --i) { @@ -155,7 +165,7 @@ static uECC_word_t vli_equal(const uECC_word_t *left, } /* Computes vli = vli >> 1. */ -static void vli_rshift1(uECC_word_t *vli, wordcount_t num_words) { +uECC_VLI_API void uECC_vli_rshift1(uECC_word_t *vli, wordcount_t num_words) { uECC_word_t *end = vli; uECC_word_t carry = 0; @@ -169,10 +179,10 @@ static void vli_rshift1(uECC_word_t *vli, wordcount_t num_words) { /* Computes result = left + right, returning carry. Can modify in place. */ #if !asm_add -static uECC_word_t vli_add(uECC_word_t *result, - const uECC_word_t *left, - const uECC_word_t *right, - wordcount_t num_words) { +uECC_VLI_API uECC_word_t uECC_vli_add(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words) { uECC_word_t carry = 0; wordcount_t i; for (i = 0; i < num_words; ++i) { @@ -188,10 +198,10 @@ static uECC_word_t vli_add(uECC_word_t *result, /* Computes result = left - right, returning borrow. Can modify in place. */ #if !asm_sub -static uECC_word_t vli_sub(uECC_word_t *result, - const uECC_word_t *left, - const uECC_word_t *right, - wordcount_t num_words) { +uECC_VLI_API uECC_word_t uECC_vli_sub(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words) { uECC_word_t borrow = 0; wordcount_t i; for (i = 0; i < num_words; ++i) { @@ -250,10 +260,10 @@ static void muladd(uECC_word_t a, #endif /* muladd needed */ #if !asm_mult -static void vli_mult(uECC_word_t *result, - const uECC_word_t *left, - const uECC_word_t *right, - wordcount_t num_words) { +uECC_VLI_API void uECC_vli_mult(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words) { uECC_word_t r0 = 0; uECC_word_t r1 = 0; uECC_word_t r2 = 0; @@ -332,7 +342,9 @@ static void mul2add(uECC_word_t a, #endif } -static void vli_square(uECC_word_t *result, const uECC_word_t *left, wordcount_t num_words) { +uECC_VLI_API void uECC_vli_square(uECC_word_t *result, + const uECC_word_t *left, + wordcount_t num_words) { uECC_word_t r0 = 0; uECC_word_t r1 = 0; uECC_word_t r2 = 0; @@ -360,63 +372,67 @@ static void vli_square(uECC_word_t *result, const uECC_word_t *left, wordcount_t #else /* uECC_SQUARE_FUNC */ -#define vli_square(result, left, size) vli_mult((result), (left), (left), (size)) - +uECC_VLI_API void uECC_vli_square(uECC_word_t *result, + const uECC_word_t *left, + wordcount_t num_words) { + uECC_vli_mult(result, left, left, num_words); +} + #endif /* uECC_SQUARE_FUNC */ /* Computes result = (left + right) % mod. Assumes that left < mod and right < mod, and that result does not overlap mod. */ -static void vli_modAdd(uECC_word_t *result, - const uECC_word_t *left, - const uECC_word_t *right, - const uECC_word_t *mod, - wordcount_t num_words) { - uECC_word_t carry = vli_add(result, left, right, num_words); - if (carry || vli_cmp(result, mod, num_words) >= 0) { +uECC_VLI_API void uECC_vli_modAdd(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + const uECC_word_t *mod, + wordcount_t num_words) { + uECC_word_t carry = uECC_vli_add(result, left, right, num_words); + if (carry || uECC_vli_cmp(result, mod, num_words) >= 0) { /* result > mod (result = mod + remainder), so subtract mod to get remainder. */ - vli_sub(result, result, mod, num_words); + uECC_vli_sub(result, result, mod, num_words); } } /* Computes result = (left - right) % mod. Assumes that left < mod and right < mod, and that result does not overlap mod. */ -static void vli_modSub(uECC_word_t *result, - const uECC_word_t *left, - const uECC_word_t *right, - const uECC_word_t *mod, - wordcount_t num_words) { - uECC_word_t l_borrow = vli_sub(result, left, right, num_words); +uECC_VLI_API void uECC_vli_modSub(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + const uECC_word_t *mod, + wordcount_t num_words) { + uECC_word_t l_borrow = uECC_vli_sub(result, left, right, num_words); if (l_borrow) { /* In this case, result == -diff == (max int) - diff. Since -x % d == d - x, we can get the correct result from result + mod (with overflow). */ - vli_add(result, result, mod, num_words); + uECC_vli_add(result, result, mod, num_words); } } /* Computes result = product % mod, where product is 2N words long. */ /* Currently only designed to work for curve_p or curve_n. */ -static void vli_mmod(uECC_word_t *result, - uECC_word_t *product, - const uECC_word_t *mod, - wordcount_t num_words) { +uECC_VLI_API void uECC_vli_mmod(uECC_word_t *result, + uECC_word_t *product, + const uECC_word_t *mod, + wordcount_t num_words) { uECC_word_t mod_multiple[2 * uECC_MAX_WORDS]; uECC_word_t tmp[2 * uECC_MAX_WORDS]; uECC_word_t *v[2] = {tmp, product}; uECC_word_t index; /* Shift mod so its highest set bit is at the maximum position. */ - bitcount_t shift = (num_words * 2 * uECC_WORD_BITS) - vli_numBits(mod, num_words); + bitcount_t shift = (num_words * 2 * uECC_WORD_BITS) - uECC_vli_numBits(mod, num_words); wordcount_t word_shift = shift / uECC_WORD_BITS; wordcount_t bit_shift = shift % uECC_WORD_BITS; uECC_word_t carry = 0; - vli_clear(mod_multiple, word_shift); + uECC_vli_clear(mod_multiple, word_shift); if (bit_shift > 0) { for(index = 0; index < (uECC_word_t)num_words; ++index) { mod_multiple[word_shift + index] = (mod[index] << bit_shift) | carry; carry = mod[index] >> (uECC_WORD_BITS - bit_shift); } } else { - vli_set(mod_multiple + word_shift, mod, num_words); + uECC_vli_set(mod_multiple + word_shift, mod, num_words); } for (index = 1; shift >= 0; --shift) { @@ -430,151 +446,145 @@ static void vli_mmod(uECC_word_t *result, v[1 - index][i] = diff; } index = !(index ^ borrow); /* Swap the index if there was no borrow */ - vli_rshift1(mod_multiple, num_words); + uECC_vli_rshift1(mod_multiple, num_words); mod_multiple[num_words - 1] |= mod_multiple[num_words] << (uECC_WORD_BITS - 1); - vli_rshift1(mod_multiple + num_words, num_words); + uECC_vli_rshift1(mod_multiple + num_words, num_words); } - vli_set(result, v[index], num_words); + uECC_vli_set(result, v[index], num_words); } /* Computes result = (left * right) % mod. */ -static void vli_modMult(uECC_word_t *result, - const uECC_word_t *left, - const uECC_word_t *right, - const uECC_word_t *mod, - wordcount_t num_words) { +uECC_VLI_API void uECC_vli_modMult(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + const uECC_word_t *mod, + wordcount_t num_words) { uECC_word_t product[2 * uECC_MAX_WORDS]; - vli_mult(product, left, right, num_words); - vli_mmod(result, product, mod, num_words); + uECC_vli_mult(product, left, right, num_words); + uECC_vli_mmod(result, product, mod, num_words); } +uECC_VLI_API void uECC_vli_modMult_fast(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + uECC_Curve curve) { + uECC_word_t product[2 * uECC_MAX_WORDS]; + uECC_vli_mult(product, left, right, curve->num_words); #if (uECC_OPTIMIZATION_LEVEL > 0) - -static void vli_modMult_fast(uECC_word_t *result, - const uECC_word_t *left, - const uECC_word_t *right, - uECC_Curve curve) { - uECC_word_t product[2 * uECC_MAX_WORDS]; - vli_mult(product, left, right, curve->num_words); curve->mmod_fast(result, product); +#else + uECC_vli_mmod(result, product, curve->p, curve->num_words); +#endif } -#else /* (uECC_OPTIMIZATION_LEVEL > 0) */ - -#define vli_modMult_fast(result, left, right, curve) \ - vli_modMult((result), (left), (right), (curve)->p, (curve)->num_words) - -#endif /* (uECC_OPTIMIZATION_LEVEL > 0) */ - #if uECC_SQUARE_FUNC /* Computes result = left^2 % mod. */ -static void vli_modSquare(uECC_word_t *result, - const uECC_word_t *left, - const uECC_word_t *mod, - wordcount_t num_words) { +uECC_VLI_API void uECC_vli_modSquare(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *mod, + wordcount_t num_words) { uECC_word_t product[2 * uECC_MAX_WORDS]; - vli_square(product, left, num_words); - vli_mmod(result, product, mod, num_words); + uECC_vli_square(product, left, num_words); + uECC_vli_mmod(result, product, mod, num_words); } +uECC_VLI_API void uECC_vli_modSquare_fast(uECC_word_t *result, + const uECC_word_t *left, + uECC_Curve curve) { + uECC_word_t product[2 * uECC_MAX_WORDS]; + uECC_vli_square(product, left, curve->num_words); #if (uECC_OPTIMIZATION_LEVEL > 0) - -static void vli_modSquare_fast(uECC_word_t *result, - const uECC_word_t *left, - uECC_Curve curve) { - uECC_word_t product[2 * uECC_MAX_WORDS]; - vli_square(product, left, curve->num_words); curve->mmod_fast(result, product); +#else + uECC_vli_mmod(result, product, curve->p, curve->num_words); +#endif } -#else /* (uECC_OPTIMIZATION_LEVEL > 0) */ - -#define vli_modSquare_fast(result, left, curve) \ - vli_modSquare((result), (left), (curve)->p, (curve)->num_words) - -#endif /* (uECC_OPTIMIZATION_LEVEL > 0) */ - #else /* uECC_SQUARE_FUNC */ -#define vli_modSquare(result, left, mod, num_words) \ - vli_modMult((result), (left), (left), (mod), (num_words)) +uECC_VLI_API void uECC_vli_modSquare(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *mod, + wordcount_t num_words) { + uECC_vli_modMult(result, left, left, mod, num_words); +} -#define vli_modSquare_fast(result, left, curve) \ - vli_modMult_fast((result), (left), (left), (curve)) +uECC_VLI_API void uECC_vli_modSquare_fast(uECC_word_t *result, + const uECC_word_t *left, + uECC_Curve curve) { + uECC_vli_modMult_fast(result, left, left, curve); +} #endif /* uECC_SQUARE_FUNC */ #define EVEN(vli) (!(vli[0] & 1)) -/* Computes result = (1 / input) % mod. All VLIs are the same size. - See "From Euclid's GCD to Montgomery Multiplication to the Great Divide" */ -#if !asm_modInv - static void vli_modInv_update(uECC_word_t *uv, const uECC_word_t *mod, wordcount_t num_words) { uECC_word_t carry = 0; if (!EVEN(uv)) { - carry = vli_add(uv, uv, mod, num_words); + carry = uECC_vli_add(uv, uv, mod, num_words); } - vli_rshift1(uv, num_words); + uECC_vli_rshift1(uv, num_words); if (carry) { uv[num_words - 1] |= HIGH_BIT_SET; } } -static void vli_modInv(uECC_word_t *result, - const uECC_word_t *input, - const uECC_word_t *mod, - wordcount_t num_words) { +/* Computes result = (1 / input) % mod. All VLIs are the same size. + See "From Euclid's GCD to Montgomery Multiplication to the Great Divide" */ +uECC_VLI_API void uECC_vli_modInv(uECC_word_t *result, + const uECC_word_t *input, + const uECC_word_t *mod, + wordcount_t num_words) { uECC_word_t a[uECC_MAX_WORDS], b[uECC_MAX_WORDS], u[uECC_MAX_WORDS], v[uECC_MAX_WORDS]; cmpresult_t cmpResult; - if (vli_isZero(input, num_words)) { - vli_clear(result, num_words); + if (uECC_vli_isZero(input, num_words)) { + uECC_vli_clear(result, num_words); return; } - vli_set(a, input, num_words); - vli_set(b, mod, num_words); - vli_clear(u, num_words); + uECC_vli_set(a, input, num_words); + uECC_vli_set(b, mod, num_words); + uECC_vli_clear(u, num_words); u[0] = 1; - vli_clear(v, num_words); - while ((cmpResult = vli_cmp(a, b, num_words)) != 0) { + uECC_vli_clear(v, num_words); + while ((cmpResult = uECC_vli_cmp(a, b, num_words)) != 0) { if (EVEN(a)) { - vli_rshift1(a, num_words); + uECC_vli_rshift1(a, num_words); vli_modInv_update(u, mod, num_words); } else if (EVEN(b)) { - vli_rshift1(b, num_words); + uECC_vli_rshift1(b, num_words); vli_modInv_update(v, mod, num_words); } else if (cmpResult > 0) { - vli_sub(a, a, b, num_words); - vli_rshift1(a, num_words); - if (vli_cmp(u, v, num_words) < 0) { - vli_add(u, u, mod, num_words); + uECC_vli_sub(a, a, b, num_words); + uECC_vli_rshift1(a, num_words); + if (uECC_vli_cmp(u, v, num_words) < 0) { + uECC_vli_add(u, u, mod, num_words); } - vli_sub(u, u, v, num_words); + uECC_vli_sub(u, u, v, num_words); vli_modInv_update(u, mod, num_words); } else { - vli_sub(b, b, a, num_words); - vli_rshift1(b, num_words); - if (vli_cmp(v, u, num_words) < 0) { - vli_add(v, v, mod, num_words); + uECC_vli_sub(b, b, a, num_words); + uECC_vli_rshift1(b, num_words); + if (uECC_vli_cmp(v, u, num_words) < 0) { + uECC_vli_add(v, v, mod, num_words); } - vli_sub(v, v, u, num_words); + uECC_vli_sub(v, v, u, num_words); vli_modInv_update(v, mod, num_words); } } - vli_set(result, u, num_words); + uECC_vli_set(result, u, num_words); } -#endif /* !asm_modInv */ /* ------ Point operations ------ */ #include "curve-specific.inc" /* Returns 1 if 'point' is the point at infinity, 0 otherwise. */ -#define EccPoint_isZero(point, curve) vli_isZero((point), (curve)->num_words * 2) +#define EccPoint_isZero(point, curve) uECC_vli_isZero((point), (curve)->num_words * 2) /* Point multiplication algorithm using Montgomery's ladder with co-Z coordinates. From http://eprint.iacr.org/2011/338.pdf @@ -587,10 +597,10 @@ static void apply_z(uECC_word_t * X1, uECC_Curve curve) { uECC_word_t t1[uECC_MAX_WORDS]; - vli_modSquare_fast(t1, Z, curve); /* z^2 */ - vli_modMult_fast(X1, X1, t1, curve); /* x1 * z^2 */ - vli_modMult_fast(t1, t1, Z, curve); /* z^3 */ - vli_modMult_fast(Y1, Y1, t1, curve); /* y1 * z^3 */ + uECC_vli_modSquare_fast(t1, Z, curve); /* z^2 */ + uECC_vli_modMult_fast(X1, X1, t1, curve); /* x1 * z^2 */ + uECC_vli_modMult_fast(t1, t1, Z, curve); /* z^3 */ + uECC_vli_modMult_fast(Y1, Y1, t1, curve); /* y1 * z^3 */ } /* P = (x1, y1) => 2P, (x2, y2) => P' */ @@ -602,14 +612,14 @@ static void XYcZ_initial_double(uECC_word_t * X1, uECC_Curve curve) { uECC_word_t z[uECC_MAX_WORDS]; if (initial_Z) { - vli_set(z, initial_Z, curve->num_words); + uECC_vli_set(z, initial_Z, curve->num_words); } else { - vli_clear(z, curve->num_words); + uECC_vli_clear(z, curve->num_words); z[0] = 1; } - vli_set(X2, X1, curve->num_words); - vli_set(Y2, Y1, curve->num_words); + uECC_vli_set(X2, X1, curve->num_words); + uECC_vli_set(Y2, Y1, curve->num_words); apply_z(X1, Y1, z, curve); curve->double_jacobian(X1, Y1, z, curve); @@ -628,22 +638,22 @@ static void XYcZ_add(uECC_word_t * X1, /* t1 = X1, t2 = Y1, t3 = X2, t4 = Y2 */ uECC_word_t t5[uECC_MAX_WORDS]; - vli_modSub(t5, X2, X1, curve->p, curve->num_words); /* t5 = x2 - x1 */ - vli_modSquare_fast(t5, t5, curve); /* t5 = (x2 - x1)^2 = A */ - vli_modMult_fast(X1, X1, t5, curve); /* t1 = x1*A = B */ - vli_modMult_fast(X2, X2, t5, curve); /* t3 = x2*A = C */ - vli_modSub(Y2, Y2, Y1, curve->p, curve->num_words); /* t4 = y2 - y1 */ - vli_modSquare_fast(t5, Y2, curve); /* t5 = (y2 - y1)^2 = D */ + uECC_vli_modSub(t5, X2, X1, curve->p, curve->num_words); /* t5 = x2 - x1 */ + uECC_vli_modSquare_fast(t5, t5, curve); /* t5 = (x2 - x1)^2 = A */ + uECC_vli_modMult_fast(X1, X1, t5, curve); /* t1 = x1*A = B */ + uECC_vli_modMult_fast(X2, X2, t5, curve); /* t3 = x2*A = C */ + uECC_vli_modSub(Y2, Y2, Y1, curve->p, curve->num_words); /* t4 = y2 - y1 */ + uECC_vli_modSquare_fast(t5, Y2, curve); /* t5 = (y2 - y1)^2 = D */ - vli_modSub(t5, t5, X1, curve->p, curve->num_words); /* t5 = D - B */ - vli_modSub(t5, t5, X2, curve->p, curve->num_words); /* t5 = D - B - C = x3 */ - vli_modSub(X2, X2, X1, curve->p, curve->num_words); /* t3 = C - B */ - vli_modMult_fast(Y1, Y1, X2, curve); /* t2 = y1*(C - B) */ - vli_modSub(X2, X1, t5, curve->p, curve->num_words); /* t3 = B - x3 */ - vli_modMult_fast(Y2, Y2, X2, curve); /* t4 = (y2 - y1)*(B - x3) */ - vli_modSub(Y2, Y2, Y1, curve->p, curve->num_words); /* t4 = y3 */ + uECC_vli_modSub(t5, t5, X1, curve->p, curve->num_words); /* t5 = D - B */ + uECC_vli_modSub(t5, t5, X2, curve->p, curve->num_words); /* t5 = D - B - C = x3 */ + uECC_vli_modSub(X2, X2, X1, curve->p, curve->num_words); /* t3 = C - B */ + uECC_vli_modMult_fast(Y1, Y1, X2, curve); /* t2 = y1*(C - B) */ + uECC_vli_modSub(X2, X1, t5, curve->p, curve->num_words); /* t3 = B - x3 */ + uECC_vli_modMult_fast(Y2, Y2, X2, curve); /* t4 = (y2 - y1)*(B - x3) */ + uECC_vli_modSub(Y2, Y2, Y1, curve->p, curve->num_words); /* t4 = y3 */ - vli_set(X2, t5, curve->num_words); + uECC_vli_set(X2, t5, curve->num_words); } /* Input P = (x1, y1, Z), Q = (x2, y2, Z) @@ -660,30 +670,30 @@ static void XYcZ_addC(uECC_word_t * X1, uECC_word_t t6[uECC_MAX_WORDS]; uECC_word_t t7[uECC_MAX_WORDS]; - vli_modSub(t5, X2, X1, curve->p, curve->num_words); /* t5 = x2 - x1 */ - vli_modSquare_fast(t5, t5, curve); /* t5 = (x2 - x1)^2 = A */ - vli_modMult_fast(X1, X1, t5, curve); /* t1 = x1*A = B */ - vli_modMult_fast(X2, X2, t5, curve); /* t3 = x2*A = C */ - vli_modAdd(t5, Y2, Y1, curve->p, curve->num_words); /* t5 = y2 + y1 */ - vli_modSub(Y2, Y2, Y1, curve->p, curve->num_words); /* t4 = y2 - y1 */ + uECC_vli_modSub(t5, X2, X1, curve->p, curve->num_words); /* t5 = x2 - x1 */ + uECC_vli_modSquare_fast(t5, t5, curve); /* t5 = (x2 - x1)^2 = A */ + uECC_vli_modMult_fast(X1, X1, t5, curve); /* t1 = x1*A = B */ + uECC_vli_modMult_fast(X2, X2, t5, curve); /* t3 = x2*A = C */ + uECC_vli_modAdd(t5, Y2, Y1, curve->p, curve->num_words); /* t5 = y2 + y1 */ + uECC_vli_modSub(Y2, Y2, Y1, curve->p, curve->num_words); /* t4 = y2 - y1 */ - vli_modSub(t6, X2, X1, curve->p, curve->num_words); /* t6 = C - B */ - vli_modMult_fast(Y1, Y1, t6, curve); /* t2 = y1 * (C - B) = E */ - vli_modAdd(t6, X1, X2, curve->p, curve->num_words); /* t6 = B + C */ - vli_modSquare_fast(X2, Y2, curve); /* t3 = (y2 - y1)^2 = D */ - vli_modSub(X2, X2, t6, curve->p, curve->num_words); /* t3 = D - (B + C) = x3 */ + uECC_vli_modSub(t6, X2, X1, curve->p, curve->num_words); /* t6 = C - B */ + uECC_vli_modMult_fast(Y1, Y1, t6, curve); /* t2 = y1 * (C - B) = E */ + uECC_vli_modAdd(t6, X1, X2, curve->p, curve->num_words); /* t6 = B + C */ + uECC_vli_modSquare_fast(X2, Y2, curve); /* t3 = (y2 - y1)^2 = D */ + uECC_vli_modSub(X2, X2, t6, curve->p, curve->num_words); /* t3 = D - (B + C) = x3 */ - vli_modSub(t7, X1, X2, curve->p, curve->num_words); /* t7 = B - x3 */ - vli_modMult_fast(Y2, Y2, t7, curve); /* t4 = (y2 - y1)*(B - x3) */ - vli_modSub(Y2, Y2, Y1, curve->p, curve->num_words); /* t4 = (y2 - y1)*(B - x3) - E = y3 */ + uECC_vli_modSub(t7, X1, X2, curve->p, curve->num_words); /* t7 = B - x3 */ + uECC_vli_modMult_fast(Y2, Y2, t7, curve); /* t4 = (y2 - y1)*(B - x3) */ + uECC_vli_modSub(Y2, Y2, Y1, curve->p, curve->num_words); /* t4 = (y2 - y1)*(B - x3) - E = y3 */ - vli_modSquare_fast(t7, t5, curve); /* t7 = (y2 + y1)^2 = F */ - vli_modSub(t7, t7, t6, curve->p, curve->num_words); /* t7 = F - (B + C) = x3' */ - vli_modSub(t6, t7, X1, curve->p, curve->num_words); /* t6 = x3' - B */ - vli_modMult_fast(t6, t6, t5, curve); /* t6 = (y2 + y1)*(x3' - B) */ - vli_modSub(Y1, t6, Y1, curve->p, curve->num_words); /* t2 = (y2 + y1)*(x3' - B) - E = y3' */ + uECC_vli_modSquare_fast(t7, t5, curve); /* t7 = (y2 + y1)^2 = F */ + uECC_vli_modSub(t7, t7, t6, curve->p, curve->num_words); /* t7 = F - (B + C) = x3' */ + uECC_vli_modSub(t6, t7, X1, curve->p, curve->num_words); /* t6 = x3' - B */ + uECC_vli_modMult_fast(t6, t6, t5, curve); /* t6 = (y2+y1)*(x3' - B) */ + uECC_vli_modSub(Y1, t6, Y1, curve->p, curve->num_words); /* t2 = (y2+y1)*(x3' - B) - E = y3' */ - vli_set(X1, t7, curve->num_words); + uECC_vli_set(X1, t7, curve->num_words); } /* result may overlap point. */ @@ -700,46 +710,46 @@ static void EccPoint_mult(uECC_word_t * result, bitcount_t i; uECC_word_t nb; - vli_set(Rx[1], point, curve->num_words); - vli_set(Ry[1], point + curve->num_words, curve->num_words); + uECC_vli_set(Rx[1], point, curve->num_words); + uECC_vli_set(Ry[1], point + curve->num_words, curve->num_words); XYcZ_initial_double(Rx[1], Ry[1], Rx[0], Ry[0], initial_Z, curve); for (i = num_bits - 2; i > 0; --i) { - nb = !vli_testBit(scalar, i); + nb = !uECC_vli_testBit(scalar, i); XYcZ_addC(Rx[1 - nb], Ry[1 - nb], Rx[nb], Ry[nb], curve); XYcZ_add(Rx[nb], Ry[nb], Rx[1 - nb], Ry[1 - nb], curve); } - nb = !vli_testBit(scalar, 0); + nb = !uECC_vli_testBit(scalar, 0); XYcZ_addC(Rx[1 - nb], Ry[1 - nb], Rx[nb], Ry[nb], curve); /* Find final 1/Z value. */ - vli_modSub(z, Rx[1], Rx[0], curve->p, curve->num_words); /* X1 - X0 */ - vli_modMult_fast(z, z, Ry[1 - nb], curve); /* Yb * (X1 - X0) */ - vli_modMult_fast(z, z, point, curve); /* xP * Yb * (X1 - X0) */ - vli_modInv(z, z, curve->p, curve->num_words); /* 1 / (xP * Yb * (X1 - X0)) */ + uECC_vli_modSub(z, Rx[1], Rx[0], curve->p, curve->num_words); /* X1 - X0 */ + uECC_vli_modMult_fast(z, z, Ry[1 - nb], curve); /* Yb * (X1 - X0) */ + uECC_vli_modMult_fast(z, z, point, curve); /* xP * Yb * (X1 - X0) */ + uECC_vli_modInv(z, z, curve->p, curve->num_words); /* 1 / (xP * Yb * (X1 - X0)) */ /* yP / (xP * Yb * (X1 - X0)) */ - vli_modMult_fast(z, z, point + curve->num_words, curve); - vli_modMult_fast(z, z, Rx[1 - nb], curve); /* Xb * yP / (xP * Yb * (X1 - X0)) */ + uECC_vli_modMult_fast(z, z, point + curve->num_words, curve); + uECC_vli_modMult_fast(z, z, Rx[1 - nb], curve); /* Xb * yP / (xP * Yb * (X1 - X0)) */ /* End 1/Z calculation */ XYcZ_add(Rx[nb], Ry[nb], Rx[1 - nb], Ry[1 - nb], curve); apply_z(Rx[0], Ry[0], z, curve); - vli_set(result, Rx[0], curve->num_words); - vli_set(result + curve->num_words, Ry[0], curve->num_words); + uECC_vli_set(result, Rx[0], curve->num_words); + uECC_vli_set(result + curve->num_words, Ry[0], curve->num_words); } static uECC_word_t regularize_k(const uECC_word_t * const k, uECC_word_t *k0, uECC_word_t *k1, uECC_Curve curve) { - bitcount_t num_bits = vli_numBits(curve->n, curve->num_n_words); - uECC_word_t carry = vli_add(k0, k, curve->n, curve->num_n_words) || + bitcount_t num_bits = uECC_vli_numBits(curve->n, curve->num_n_words); + uECC_word_t carry = uECC_vli_add(k0, k, curve->n, curve->num_n_words) || (num_bits < ((bitcount_t)curve->num_n_words * uECC_WORD_SIZE * 8) && - vli_testBit(k0, num_bits)); - vli_add(k1, k0, curve->n, curve->num_n_words); + uECC_vli_testBit(k0, num_bits)); + uECC_vli_add(k1, k0, curve->n, curve->num_n_words); return carry; } @@ -752,11 +762,11 @@ static uECC_word_t EccPoint_compute_public_key(uECC_word_t *result, uECC_word_t carry; /* Make sure the private key is in the range [1, n-1]. */ - if (vli_isZero(private, curve->num_words)) { + if (uECC_vli_isZero(private, curve->num_words)) { return 0; } - if (vli_cmp(curve->n, private, curve->num_n_words) != 1) { + if (uECC_vli_cmp(curve->n, private, curve->num_n_words) != 1) { return 0; } @@ -765,7 +775,7 @@ static uECC_word_t EccPoint_compute_public_key(uECC_word_t *result, carry = regularize_k(private, tmp1, tmp2, curve); EccPoint_mult(result, curve->G, p2[!carry], 0, - vli_numBits(curve->n, curve->num_n_words) + 1, + uECC_vli_numBits(curve->n, curve->num_n_words) + 1, curve); if (EccPoint_isZero(result, curve)) { @@ -776,18 +786,20 @@ static uECC_word_t EccPoint_compute_public_key(uECC_word_t *result, #if uECC_WORD_SIZE == 1 -static void vli_nativeToBytes(uint8_t * dest, const uint8_t * src, uECC_Curve curve) { +uECC_VLI_API void uECC_vli_nativeToBytes(uint8_t *bytes, const uint8_t *native, uECC_Curve curve) { wordcount_t i; for (i = 0; i < curve->num_words; ++i) { dest[i] = src[(curve->num_words - 1) - i]; } } -#define vli_bytesToNative(dest, src, curve) vli_nativeToBytes((dest), (src), (curve)) +uECC_VLI_API void uECC_vli_bytesToNative(uint8_t *native, const uint8_t *bytes, uECC_Curve curve) { + uECC_vli_nativeToBytes(dest, src, curve); +} #elif uECC_WORD_SIZE == 4 -static void vli_nativeToBytes(uint8_t *bytes, const uint32_t *native, uECC_Curve curve) { +uECC_VLI_API void uECC_vli_nativeToBytes(uint8_t *bytes, const uint32_t *native, uECC_Curve curve) { wordcount_t i; for (i = 0; i < curve->num_words; ++i) { uint8_t *digit = bytes + 4 * (curve->num_words - 1 - i); @@ -798,7 +810,7 @@ static void vli_nativeToBytes(uint8_t *bytes, const uint32_t *native, uECC_Curve } } -static void vli_bytesToNative(uint32_t *native, const uint8_t *bytes, uECC_Curve curve) { +uECC_VLI_API void uECC_vli_bytesToNative(uint32_t *native, const uint8_t *bytes, uECC_Curve curve) { wordcount_t i; for (i = 0; i < curve->num_words; ++i) { const uint8_t *digit = bytes + 4 * (curve->num_words - 1 - i); @@ -809,7 +821,7 @@ static void vli_bytesToNative(uint32_t *native, const uint8_t *bytes, uECC_Curve #else -static void vli_nativeToBytes(uint8_t *bytes, const uint64_t *native, uECC_Curve curve) { +uECC_VLI_API void uECC_vli_nativeToBytes(uint8_t *bytes, const uint64_t *native, uECC_Curve curve) { wordcount_t i; for (i = 0; i < curve->num_bytes; ++i) { unsigned b = curve->num_bytes - 1 - i; @@ -817,9 +829,9 @@ static void vli_nativeToBytes(uint8_t *bytes, const uint64_t *native, uECC_Curve } } -static void vli_bytesToNative(uint64_t *native, const uint8_t *bytes, uECC_Curve curve) { +uECC_VLI_API void uECC_vli_bytesToNative(uint64_t *native, const uint8_t *bytes, uECC_Curve curve) { wordcount_t i; - vli_clear(native, curve->num_words); + uECC_vli_clear(native, curve->num_words); for (i = 0; i < curve->num_bytes; ++i) { unsigned b = curve->num_bytes - 1 - i; native[b / 8] |= (uint64_t)bytes[i] << (8 * (b % 8)); @@ -859,9 +871,9 @@ int uECC_make_key(uint8_t *public_key, } if (EccPoint_compute_public_key(public, private, curve)) { - vli_nativeToBytes(private_key, private, curve); - vli_nativeToBytes(public_key, public, curve); - vli_nativeToBytes(public_key + curve->num_bytes, public + curve->num_words, curve); + uECC_vli_nativeToBytes(private_key, private, curve); + uECC_vli_nativeToBytes(public_key, public, curve); + uECC_vli_nativeToBytes(public_key + curve->num_bytes, public + curve->num_words, curve); return 1; } } @@ -883,9 +895,9 @@ int uECC_shared_secret(const uint8_t *public_key, /* Zero out correctly (for addition with curve->n) for secp160r1. */ private[curve->num_n_words - 1] = 0; - vli_bytesToNative(private, private_key, curve); - vli_bytesToNative(public, public_key, curve); - vli_bytesToNative(public + curve->num_words, public_key + curve->num_bytes, curve); + uECC_vli_bytesToNative(private, private_key, curve); + uECC_vli_bytesToNative(public, public_key, curve); + uECC_vli_bytesToNative(public + curve->num_words, public_key + curve->num_bytes, curve); /* Regularize the bitcount for the private key so that attackers cannot use a side channel attack to learn the number of leading zeros. */ @@ -899,8 +911,8 @@ int uECC_shared_secret(const uint8_t *public_key, return 0; } - if (!vli_isZero(p2[carry], curve->num_words) && - vli_cmp(curve->p, p2[carry], curve->num_words) == 1) { + if (!uECC_vli_isZero(p2[carry], curve->num_words) && + uECC_vli_cmp(curve->p, p2[carry], curve->num_words) == 1) { initial_Z = p2[carry]; break; } @@ -908,9 +920,9 @@ int uECC_shared_secret(const uint8_t *public_key, } EccPoint_mult(public, public, p2[!carry], initial_Z, - vli_numBits(curve->n, curve->num_n_words) + 1, + uECC_vli_numBits(curve->n, curve->num_n_words) + 1, curve); - vli_nativeToBytes(secret, public, curve); + uECC_vli_nativeToBytes(secret, public, curve); return !EccPoint_isZero(public, curve); } @@ -926,16 +938,16 @@ void uECC_compress(const uint8_t *public_key, uint8_t *compressed, uECC_Curve cu void uECC_decompress(const uint8_t *compressed, uint8_t *public_key, uECC_Curve curve) { uECC_word_t point[uECC_MAX_WORDS * 2]; uECC_word_t *y = point + curve->num_words; - vli_bytesToNative(point, compressed + 1, curve); + uECC_vli_bytesToNative(point, compressed + 1, curve); curve->x_side(y, point, curve); curve->mod_sqrt(y, curve); if ((y[0] & 0x01) != (compressed[0] & 0x01)) { - vli_sub(y, curve->p, y, curve->num_words); + uECC_vli_sub(y, curve->p, y, curve->num_words); } - vli_nativeToBytes(public_key, point, curve); - vli_nativeToBytes(public_key + curve->num_bytes, y, curve); + uECC_vli_nativeToBytes(public_key, point, curve); + uECC_vli_nativeToBytes(public_key + curve->num_bytes, y, curve); } #endif /* uECC_SUPPORT_COMPRESSED_POINT */ @@ -949,23 +961,23 @@ int uECC_valid_point(const uECC_word_t *point, uECC_Curve curve) { } /* x and y must be smaller than p. */ - if (vli_cmp(curve->p, point, curve->num_words) != 1 || - vli_cmp(curve->p, point + curve->num_words, curve->num_words) != 1) { + if (uECC_vli_cmp(curve->p, point, curve->num_words) != 1 || + uECC_vli_cmp(curve->p, point + curve->num_words, curve->num_words) != 1) { return 0; } - vli_modSquare_fast(tmp1, point + curve->num_words, curve); + uECC_vli_modSquare_fast(tmp1, point + curve->num_words, curve); curve->x_side(tmp2, point, curve); /* tmp2 = x^3 + ax + b */ /* Make sure that y^2 == x^3 + ax + b */ - return (vli_equal(tmp1, tmp2, curve->num_words)); + return (uECC_vli_equal(tmp1, tmp2, curve->num_words)); } int uECC_valid_public_key(const uint8_t *public_key, uECC_Curve curve) { uECC_word_t public[uECC_MAX_WORDS * 2]; - vli_bytesToNative(public, public_key, curve); - vli_bytesToNative(public + curve->num_words, public_key + curve->num_bytes, curve); + uECC_vli_bytesToNative(public, public_key, curve); + uECC_vli_bytesToNative(public + curve->num_words, public_key + curve->num_bytes, curve); return uECC_valid_point(public, curve); } @@ -973,14 +985,14 @@ int uECC_compute_public_key(const uint8_t *private_key, uint8_t *public_key, uEC uECC_word_t private[uECC_MAX_WORDS]; uECC_word_t public[uECC_MAX_WORDS * 2]; - vli_bytesToNative(private, private_key, curve); + uECC_vli_bytesToNative(private, private_key, curve); if (!EccPoint_compute_public_key(public, private, curve)) { return 0; } - vli_nativeToBytes(public_key, public, curve); - vli_nativeToBytes(public_key + curve->num_bytes, public + curve->num_words, curve); + uECC_vli_nativeToBytes(public_key, public, curve); + uECC_vli_nativeToBytes(public_key + curve->num_bytes, public + curve->num_words, curve); return 1; } @@ -997,22 +1009,23 @@ static int uECC_sign_with_k(const uint8_t *private_key, uECC_word_t *k2[2] = {tmp, s}; uECC_word_t p[uECC_MAX_WORDS * 2]; uECC_word_t carry; - bitcount_t num_n_bits = vli_numBits(curve->n, curve->num_n_words); + bitcount_t num_n_bits = uECC_vli_numBits(curve->n, curve->num_n_words); /* Make sure 0 < k < curve_n */ - if (vli_isZero(k, curve->num_words) || vli_cmp(curve->n, k, curve->num_n_words) != 1) { + if (uECC_vli_isZero(k, curve->num_words) || + uECC_vli_cmp(curve->n, k, curve->num_n_words) != 1) { return 0; } carry = regularize_k(k, tmp, s, curve); EccPoint_mult(p, curve->G, k2[!carry], 0, num_n_bits + 1, curve); - if (vli_isZero(p, curve->num_words)) { + if (uECC_vli_isZero(p, curve->num_words)) { return 0; } /* Attempt to get a random number to prevent side channel analysis of k. */ if (!g_rng_function) { - vli_clear(tmp, curve->num_n_words); + uECC_vli_clear(tmp, curve->num_n_words); tmp[0] = 1; } else { uECC_word_t tries; @@ -1021,35 +1034,35 @@ static int uECC_sign_with_k(const uint8_t *private_key, return 0; } - if (!vli_isZero(tmp, curve->num_n_words) && - vli_cmp(curve->n, tmp, curve->num_n_words) == 1) { + if (!uECC_vli_isZero(tmp, curve->num_n_words) && + uECC_vli_cmp(curve->n, tmp, curve->num_n_words) == 1) { goto got_random; } } return 0; } got_random: - /* Prevent side channel analysis of vli_modInv() to determine + /* Prevent side channel analysis of uECC_vli_modInv() to determine bits of k / the private key by premultiplying by a random number */ - vli_modMult(k, k, tmp, curve->n, curve->num_n_words); /* k' = rand * k */ - vli_modInv(k, k, curve->n, curve->num_n_words); /* k = 1 / k' */ - vli_modMult(k, k, tmp, curve->n, curve->num_n_words); /* k = 1 / k */ + uECC_vli_modMult(k, k, tmp, curve->n, curve->num_n_words); /* k' = rand * k */ + uECC_vli_modInv(k, k, curve->n, curve->num_n_words); /* k = 1 / k' */ + uECC_vli_modMult(k, k, tmp, curve->n, curve->num_n_words); /* k = 1 / k */ - vli_nativeToBytes(signature, p, curve); /* store r */ + uECC_vli_nativeToBytes(signature, p, curve); /* store r */ tmp[curve->num_n_words - 1] = 0; - vli_bytesToNative(tmp, private_key, curve); /* tmp = d */ + uECC_vli_bytesToNative(tmp, private_key, curve); /* tmp = d */ s[curve->num_n_words - 1] = 0; - vli_set(s, p, curve->num_words); - vli_modMult(s, tmp, s, curve->n, curve->num_n_words); /* s = r*d */ + uECC_vli_set(s, p, curve->num_words); + uECC_vli_modMult(s, tmp, s, curve->n, curve->num_n_words); /* s = r*d */ - vli_bytesToNative(tmp, message_hash, curve); - vli_modAdd(s, tmp, s, curve->n, curve->num_n_words); /* s = e + r*d */ - vli_modMult(s, s, k, curve->n, curve->num_n_words); /* s = (e + r*d) / k */ - if (vli_numBits(s, curve->num_n_words) > (bitcount_t)curve->num_bytes * 8) { + uECC_vli_bytesToNative(tmp, message_hash, curve); + uECC_vli_modAdd(s, tmp, s, curve->n, curve->num_n_words); /* s = e + r*d */ + uECC_vli_modMult(s, s, k, curve->n, curve->num_n_words); /* s = (e + r*d) / k */ + if (uECC_vli_numBits(s, curve->num_n_words) > (bitcount_t)curve->num_bytes * 8) { return 0; } - vli_nativeToBytes(signature + curve->num_bytes, s, curve); + uECC_vli_nativeToBytes(signature + curve->num_bytes, s, curve); return 1; } @@ -1059,7 +1072,7 @@ int uECC_sign(const uint8_t *private_key, uECC_Curve curve) { uECC_word_t k[uECC_MAX_WORDS]; uECC_word_t tries; - bitcount_t num_n_bits = vli_numBits(curve->n, curve->num_n_words); + bitcount_t num_n_bits = uECC_vli_numBits(curve->n, curve->num_n_words); for (tries = 0; tries < MAX_TRIES; ++tries) { if (!generate_random_int(k, curve->num_n_words, num_n_bits)) { @@ -1129,7 +1142,7 @@ int uECC_sign_deterministic(const uint8_t *private_key, uECC_Curve curve) { uint8_t *K = hash_context->tmp; uint8_t *V = K + hash_context->result_size; - bitcount_t num_n_bits = vli_numBits(curve->n, curve->num_n_words); + bitcount_t num_n_bits = uECC_vli_numBits(curve->n, curve->num_n_words); uECC_word_t tries; unsigned i; for (i = 0; i < hash_context->result_size; ++i) { @@ -1220,37 +1233,37 @@ int uECC_verify(const uint8_t *public_key, r[curve->num_n_words - 1] = 0; s[curve->num_n_words - 1] = 0; - vli_bytesToNative(public, public_key, curve); - vli_bytesToNative(public + curve->num_words, public_key + curve->num_bytes, curve); - vli_bytesToNative(r, signature, curve); - vli_bytesToNative(s, signature + curve->num_bytes, curve); + uECC_vli_bytesToNative(public, public_key, curve); + uECC_vli_bytesToNative(public + curve->num_words, public_key + curve->num_bytes, curve); + uECC_vli_bytesToNative(r, signature, curve); + uECC_vli_bytesToNative(s, signature + curve->num_bytes, curve); /* r, s must not be 0. */ - if (vli_isZero(r, curve->num_words) || vli_isZero(s, curve->num_words)) { + if (uECC_vli_isZero(r, curve->num_words) || uECC_vli_isZero(s, curve->num_words)) { return 0; } /* r, s must be < n. */ - if (vli_cmp(curve->n, r, curve->num_n_words) != 1 || - vli_cmp(curve->n, s, curve->num_n_words) != 1) { + if (uECC_vli_cmp(curve->n, r, curve->num_n_words) != 1 || + uECC_vli_cmp(curve->n, s, curve->num_n_words) != 1) { return 0; } /* Calculate u1 and u2. */ - vli_modInv(z, s, curve->n, curve->num_n_words); /* z = 1/s */ + uECC_vli_modInv(z, s, curve->n, curve->num_n_words); /* z = 1/s */ u1[curve->num_n_words - 1] = 0; - vli_bytesToNative(u1, hash, curve); - vli_modMult(u1, u1, z, curve->n, curve->num_n_words); /* u1 = e/s */ - vli_modMult(u2, r, z, curve->n, curve->num_n_words); /* u2 = r/s */ + uECC_vli_bytesToNative(u1, hash, curve); + uECC_vli_modMult(u1, u1, z, curve->n, curve->num_n_words); /* u1 = e/s */ + uECC_vli_modMult(u2, r, z, curve->n, curve->num_n_words); /* u2 = r/s */ /* Calculate sum = G + Q. */ - vli_set(sum, public, curve->num_words); - vli_set(sum + curve->num_words, public + curve->num_words, curve->num_words); - vli_set(tx, curve->G, curve->num_words); - vli_set(ty, curve->G + curve->num_words, curve->num_words); - vli_modSub(z, sum, tx, curve->p, curve->num_words); /* z = x2 - x1 */ + uECC_vli_set(sum, public, curve->num_words); + uECC_vli_set(sum + curve->num_words, public + curve->num_words, curve->num_words); + uECC_vli_set(tx, curve->G, curve->num_words); + uECC_vli_set(ty, curve->G + curve->num_words, curve->num_words); + uECC_vli_modSub(z, sum, tx, curve->p, curve->num_words); /* z = x2 - x1 */ XYcZ_add(tx, ty, sum, sum + curve->num_words, curve); - vli_modInv(z, z, curve->p, curve->num_words); /* z = 1/z */ + uECC_vli_modInv(z, z, curve->p, curve->num_words); /* z = 1/z */ apply_z(sum, sum + curve->num_words, z, curve); /* Use Shamir's trick to calculate u1*G + u2*Q */ @@ -1258,44 +1271,46 @@ int uECC_verify(const uint8_t *public_key, points[1] = curve->G; points[2] = public; points[3] = sum; - num_bits = smax(vli_numBits(u1, curve->num_n_words), vli_numBits(u2, curve->num_n_words)); + num_bits = smax(uECC_vli_numBits(u1, curve->num_n_words), + uECC_vli_numBits(u2, curve->num_n_words)); - point = points[(!!vli_testBit(u1, num_bits - 1)) | ((!!vli_testBit(u2, num_bits - 1)) << 1)]; - vli_set(rx, point, curve->num_words); - vli_set(ry, point + curve->num_words, curve->num_words); - vli_clear(z, curve->num_words); + point = points[(!!uECC_vli_testBit(u1, num_bits - 1)) | + ((!!uECC_vli_testBit(u2, num_bits - 1)) << 1)]; + uECC_vli_set(rx, point, curve->num_words); + uECC_vli_set(ry, point + curve->num_words, curve->num_words); + uECC_vli_clear(z, curve->num_words); z[0] = 1; for (i = num_bits - 2; i >= 0; --i) { uECC_word_t index; curve->double_jacobian(rx, ry, z, curve); - index = (!!vli_testBit(u1, i)) | ((!!vli_testBit(u2, i)) << 1); + index = (!!uECC_vli_testBit(u1, i)) | ((!!uECC_vli_testBit(u2, i)) << 1); point = points[index]; if (point) { - vli_set(tx, point, curve->num_words); - vli_set(ty, point + curve->num_words, curve->num_words); + uECC_vli_set(tx, point, curve->num_words); + uECC_vli_set(ty, point + curve->num_words, curve->num_words); apply_z(tx, ty, z, curve); - vli_modSub(tz, rx, tx, curve->p, curve->num_words); /* Z = x2 - x1 */ + uECC_vli_modSub(tz, rx, tx, curve->p, curve->num_words); /* Z = x2 - x1 */ XYcZ_add(tx, ty, rx, ry, curve); - vli_modMult_fast(z, z, tz, curve); + uECC_vli_modMult_fast(z, z, tz, curve); } } - vli_modInv(z, z, curve->p, curve->num_words); /* Z = 1/Z */ + uECC_vli_modInv(z, z, curve->p, curve->num_words); /* Z = 1/Z */ apply_z(rx, ry, z, curve); /* v = x1 (mod n) */ - if (vli_cmp(curve->n, rx, curve->num_n_words) != 1) { - vli_sub(rx, rx, curve->n, curve->num_n_words); + if (uECC_vli_cmp(curve->n, rx, curve->num_n_words) != 1) { + uECC_vli_sub(rx, rx, curve->n, curve->num_n_words); } /* Accept only if v == r. */ - return (vli_equal(rx, r, curve->num_words)); + return (uECC_vli_equal(rx, r, curve->num_words)); } +#if uECC_ENABLE_VLI_API -/* -------- "Internal" API -------- */ unsigned uECC_curve_num_words(uECC_Curve curve) { return curve->num_words; } @@ -1326,127 +1341,21 @@ const uECC_word_t *uECC_curve_b(uECC_Curve curve) { #if uECC_SUPPORT_COMPRESSED_POINT /* Calculates a = sqrt(a) (mod curve->p) */ -void uECC_mod_sqrt(uECC_word_t *a, uECC_Curve curve) { +void uECC_vli_mod_sqrt(uECC_word_t *a, uECC_Curve curve) { curve->mod_sqrt(a, curve); } #endif /* Calculates result = product (mod curve->p), where product is up to 2 * curve->num_words long. */ -void uECC_mmod_fast(uECC_word_t *result, uECC_word_t *product, uECC_Curve curve) { +void uECC_vli_mmod_fast(uECC_word_t *result, uECC_word_t *product, uECC_Curve curve) { #if (uECC_OPTIMIZATION_LEVEL > 0) curve->mmod_fast(result, product); #else - vli_mmod(result, product, curve->p, curve->num_words); + uECC_vli_mmod(result, product, curve->p, curve->num_words); #endif } -void uECC_vli_nativeToBytes(uint8_t * dest, const uECC_word_t * src, uECC_Curve curve) { - vli_nativeToBytes(dest, src, curve); -} - -void uECC_vli_bytesToNative(uECC_word_t * dest, const uint8_t * src, uECC_Curve curve) { - vli_bytesToNative(dest, src, curve); -} - -void uECC_vli_clear(uECC_word_t *vli, unsigned num_words) { - vli_clear(vli, num_words); -} - -int uECC_vli_isZero(const uECC_word_t *vli, unsigned num_words) { - return vli_isZero(vli, num_words); -} - -int uECC_vli_testBit(const uECC_word_t *vli, unsigned bit) { - return vli_testBit(vli, bit); -} - -unsigned uECC_vli_numBits(const uECC_word_t *vli, unsigned max_words) { - return uECC_vli_numBits(vli, max_words); -} - -void uECC_vli_set(uECC_word_t *dest, const uECC_word_t *src, unsigned num_words) { - vli_set(dest, src, num_words); -} - -int uECC_vli_cmp(const uECC_word_t *left, - const uECC_word_t *right, - unsigned num_words) { - return vli_cmp(left, right, num_words); -} - -int uECC_vli_equal(const uECC_word_t *left, - const uECC_word_t *right, - unsigned num_words) { - return vli_equal(left, right, num_words); -} - -void uECC_vli_rshift1(uECC_word_t *vli, unsigned num_words) { - vli_rshift1(vli, num_words); -} - -uECC_word_t uECC_vli_add(uECC_word_t *result, - const uECC_word_t *left, - const uECC_word_t *right, - unsigned num_words) { - return vli_add(result, left, right, num_words); -} - -uECC_word_t uECC_vli_sub(uECC_word_t *result, - const uECC_word_t *left, - const uECC_word_t *right, - unsigned num_words) { - return vli_sub(result, left, right, num_words); -} - -void uECC_vli_mult(uECC_word_t *result, - const uECC_word_t *left, - const uECC_word_t *right, - unsigned num_words) { - vli_mult(result, left, right, num_words); -} - -void uECC_vli_square(uECC_word_t *result, const uECC_word_t *left, unsigned num_words) { - vli_square(result, left, num_words); -} - -/* Computes result = (left + right) % mod. - Assumes that left < mod and right < mod, and that result does not overlap mod. */ -void uECC_vli_modAdd(uECC_word_t *result, - const uECC_word_t *left, - const uECC_word_t *right, - const uECC_word_t *mod, - unsigned num_words) { - vli_modAdd(result, left, right, mod, num_words); -} - -/* Computes result = (left - right) % mod. - Assumes that left < mod and right < mod, and that result does not overlap mod. */ -void uECC_vli_modSub(uECC_word_t *result, - const uECC_word_t *left, - const uECC_word_t *right, - const uECC_word_t *mod, - unsigned num_words) { - vli_modSub(result, left, right, mod, num_words); -} - -/* Computes result = product % mod, where product is 2 * num_words long. */ -/* Currently only designed to work for curve_p or curve_n. */ -void uECC_vli_mmod(uECC_word_t *result, - uECC_word_t *product, - const uECC_word_t *mod, - unsigned num_words) { - vli_mmod(result, product, mod, num_words); -} - -/* Computes result = 1 / input (mod m) */ -void uECC_vli_modInv(uECC_word_t *result, - const uECC_word_t *input, - const uECC_word_t *m, - unsigned num_words) { - vli_modInv(result, input, m, num_words); -} - /* Multiply a point by a scalar. Points are represented by the X coordinate followed by the Y coordinate in the same array, both coordinates are curve->num_words long. Note that scalar must be curve->num_n_words long (NOT curve->num_words). */ @@ -1460,28 +1369,8 @@ void uECC_point_mult(uECC_word_t *result, uECC_word_t carry = regularize_k(scalar, tmp1, tmp2, curve); EccPoint_mult(result, point, p2[!carry], 0, - vli_numBits(curve->n, curve->num_n_words) + 1, + uECC_vli_numBits(curve->n, curve->num_n_words) + 1, curve); } -/* Calculates result = product (mod curve->n), where product is up to - 2 * curve->num_n_words long. */ -void uECC_vli_mmod_n(uECC_word_t *result, uECC_word_t *product, uECC_Curve curve) { - vli_mmod(result, product, curve->n, curve->num_n_words); -} - -/* Computes result = (left * right) % (curve->n). */ -void uECC_vli_modMult_n(uECC_word_t *result, - const uECC_word_t *left, - const uECC_word_t *right, - uECC_Curve curve) { - vli_modMult(result, left, right, curve->n, curve->num_n_words); -} - -/* Computes result = (left * right) % (curve->p). */ -void uECC_vli_modMult_fast(uECC_word_t *result, - const uECC_word_t *left, - const uECC_word_t *right, - uECC_Curve curve) { - vli_modMult_fast(result, left, right, curve); -} +#endif /* uECC_ENABLE_VLI_API */ diff --git a/uECC.h b/uECC.h index a5e97a0..a5feb7f 100644 --- a/uECC.h +++ b/uECC.h @@ -50,9 +50,9 @@ platform. */ #endif /* Specifies whether compressed point format is supported. - Set to 0 if compressed point is not supported. That saves code size. */ + Set to 0 to disable point compression/decompression functions. */ #ifndef uECC_SUPPORT_COMPRESSED_POINT - #define uECC_SUPPORT_COMPRESSED_POINT 0 + #define uECC_SUPPORT_COMPRESSED_POINT 1 #endif struct uECC_Curve_t; diff --git a/uECC_vli.h b/uECC_vli.h new file mode 100644 index 0000000..3145706 --- /dev/null +++ b/uECC_vli.h @@ -0,0 +1,149 @@ +/* Copyright 2015, Kenneth MacKay. Licensed under the BSD 2-clause license. */ + +#ifndef _UECC_VLI_H_ +#define _UECC_VLI_H_ + +#include "uECC.h" +#include "types.inc" + +/* Functions for raw large-integer manipulation. These are only available + if uECC.c is compiled with uECC_ENABLE_VLI_API defined to 1. */ + +#ifdef __cplusplus +extern "C" +{ +#endif + +void uECC_vli_clear(uECC_word_t *vli, wordcount_t num_words); + +/* Constant-time comparison to zero - secure way to compare long integers */ +/* Returns 1 if vli == 0, 0 otherwise. */ +uECC_word_t uECC_vli_isZero(const uECC_word_t *vli, wordcount_t num_words); + +/* Returns nonzero if bit 'bit' of vli is set. */ +uECC_word_t uECC_vli_testBit(const uECC_word_t *vli, bitcount_t bit); + +/* Counts the number of bits required to represent vli. */ +bitcount_t uECC_vli_numBits(const uECC_word_t *vli, const wordcount_t max_words); + +/* Sets dest = src. */ +void uECC_vli_set(uECC_word_t *dest, const uECC_word_t *src, wordcount_t num_words); + +/* Returns sign of left - right. */ +cmpresult_t uECC_vli_cmp(const uECC_word_t *left, const uECC_word_t *right, wordcount_t num_words); + +/* Constant-time comparison function - secure way to compare long integers */ +/* Returns one if left == right, zero otherwise */ +uECC_word_t uECC_vli_equal(const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words); + +/* Computes vli = vli >> 1. */ +void uECC_vli_rshift1(uECC_word_t *vli, wordcount_t num_words); + +/* Computes result = left + right, returning carry. Can modify in place. */ +uECC_word_t uECC_vli_add(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words); + +/* Computes result = left - right, returning borrow. Can modify in place. */ +uECC_word_t uECC_vli_sub(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words); + +void uECC_vli_mult(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words); + +void uECC_vli_square(uECC_word_t *result, const uECC_word_t *left, wordcount_t num_words); + +/* Computes result = (left + right) % mod. + Assumes that left < mod and right < mod, and that result does not overlap mod. */ +void uECC_vli_modAdd(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + const uECC_word_t *mod, + wordcount_t num_words); + +/* Computes result = (left - right) % mod. + Assumes that left < mod and right < mod, and that result does not overlap mod. */ +void uECC_vli_modSub(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + const uECC_word_t *mod, + wordcount_t num_words); + +/* Computes result = product % mod, where product is 2N words long. + Currently only designed to work for mod == curve->p or curve_n. */ +void uECC_vli_mmod(uECC_word_t *result, + uECC_word_t *product, + const uECC_word_t *mod, + wordcount_t num_words); + +/* Calculates result = product (mod curve->p), where product is up to + 2 * curve->num_words long. */ +void uECC_vli_mmod_fast(uECC_word_t *result, uECC_word_t *product, uECC_Curve curve); + +/* Computes result = (left * right) % mod. + Currently only designed to work for mod == curve->p or curve_n. */ +void uECC_vli_modMult(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + const uECC_word_t *mod, + wordcount_t num_words); + +/* Computes result = (left * right) % curve->p. */ +void uECC_vli_modMult_fast(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + uECC_Curve curve); + +/* Computes result = left^2 % mod. + Currently only designed to work for mod == curve->p or curve_n. */ +void uECC_vli_modSquare(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *mod, + wordcount_t num_words); + +/* Computes result = left^2 % curve->p. */ +void uECC_vli_modSquare_fast(uECC_word_t *result, const uECC_word_t *left, uECC_Curve curve); + +/* Computes result = (1 / input) % mod.*/ +void uECC_vli_modInv(uECC_word_t *result, + const uECC_word_t *input, + const uECC_word_t *mod, + wordcount_t num_words); + +#if uECC_SUPPORT_COMPRESSED_POINT +/* Calculates a = sqrt(a) (mod curve->p) */ +void uECC_vli_mod_sqrt(uECC_word_t *a, uECC_Curve curve); +#endif + +void uECC_vli_nativeToBytes(uint8_t *bytes, const uECC_word_t *native, uECC_Curve curve); +void uECC_vli_bytesToNative(uECC_word_t *native, const uint8_t *bytes, uECC_Curve curve); + +unsigned uECC_curve_num_words(uECC_Curve curve); +unsigned uECC_curve_num_bits(uECC_Curve curve); +unsigned uECC_curve_num_n_words(uECC_Curve curve); + +const uECC_word_t *uECC_curve_p(uECC_Curve curve); +const uECC_word_t *uECC_curve_n(uECC_Curve curve); +const uECC_word_t *uECC_curve_G(uECC_Curve curve); +const uECC_word_t *uECC_curve_b(uECC_Curve curve); + +/* Multiply a point by a scalar. Points are represented by the X coordinate followed by + the Y coordinate in the same array, both coordinates are curve->num_words long. Note + that scalar must be curve->num_n_words long (NOT curve->num_words). */ +void uECC_point_mult(uECC_word_t *result, + const uECC_word_t *point, + const uECC_word_t *scalar, + uECC_Curve curve); + +#ifdef __cplusplus +} /* end of extern "C" */ +#endif + +#endif /* _UECC_VLI_H_ */