From 5f01beb71709cec4882e70648fe0863162bce278 Mon Sep 17 00:00:00 2001 From: Ken MacKay Date: Sat, 1 Aug 2015 14:34:58 -0700 Subject: [PATCH] Add fast ARM asm; cleaned up code. Added optimization setting. (#50) --- asm_arm.inc | 2455 --------------------------------------- asm_arm_fast.inc | 845 ++++++++++++++ asm_arm_mult_square.inc | 1808 ++++++++++++++++++++++++++++ asm_arm_small.inc | 23 +- curve-specific.inc | 838 ++++++------- platform-specific.inc | 41 +- uECC.c | 109 +- uECC.h | 41 +- 8 files changed, 3253 insertions(+), 2907 deletions(-) delete mode 100644 asm_arm.inc create mode 100644 asm_arm_fast.inc create mode 100644 asm_arm_mult_square.inc diff --git a/asm_arm.inc b/asm_arm.inc deleted file mode 100644 index 24e57e3..0000000 --- a/asm_arm.inc +++ /dev/null @@ -1,2455 +0,0 @@ -#define DEC_5 4 -#define DEC_6 5 -#define DEC_7 6 -#define DEC_8 7 - -#define DEC(N) uECC_CONCAT(DEC_, N) - -#define REPEAT_1(stuff) stuff -#define REPEAT_2(stuff) REPEAT_1(stuff) stuff -#define REPEAT_3(stuff) REPEAT_2(stuff) stuff -#define REPEAT_4(stuff) REPEAT_3(stuff) stuff -#define REPEAT_5(stuff) REPEAT_4(stuff) stuff -#define REPEAT_6(stuff) REPEAT_5(stuff) stuff -#define REPEAT_7(stuff) REPEAT_6(stuff) stuff -#define REPEAT_8(stuff) REPEAT_7(stuff) stuff - -#define REPEAT(N, stuff) uECC_CONCAT(REPEAT_, N)(stuff) - -#define STR2(thing) #thing -#define STR(thing) STR2(thing) - -#if (uECC_ASM == uECC_asm_fast) - -static uint32_t vli_add(uint32_t *result, const uint32_t *left, const uint32_t *right) { - uint32_t carry = 0; - uint32_t left_word; - uint32_t right_word; - - __asm__ volatile ( - ".syntax unified \n\t" - "ldmia %[lptr]!, {%[left]} \n\t" /* Load left word. */ - "ldmia %[rptr]!, {%[right]} \n\t" /* Load right word. */ - "adds %[left], %[right] \n\t" /* Add first word. */ - "stmia %[dptr]!, {%[left]} \n\t" /* Store result word. */ - - /* Now we just do the remaining words with the carry bit (using ADC) */ - REPEAT(DEC(uECC_WORDS), - "ldmia %[lptr]!, {%[left]} \n\t" - "ldmia %[rptr]!, {%[right]} \n\t" - "adcs %[left], %[right] \n\t" - "stmia %[dptr]!, {%[left]} \n\t") - - "adcs %[carry], %[carry] \n\t" /* Store carry bit. */ - #if (uECC_PLATFORM != uECC_arm_thumb2) - ".syntax divided \n\t" - #endif - #if (uECC_PLATFORM == uECC_arm_thumb) - : [dptr] "+l" (result), [lptr] "+l" (left), [rptr] "+l" (right), - [carry] "+l" (carry), [left] "=l" (left_word), [right] "=l" (right_word) - #else - : [dptr] "+r" (result), [lptr] "+r" (left), [rptr] "+r" (right), - [carry] "+r" (carry), [left] "=r" (left_word), [right] "=r" (right_word) - #endif - : - : "cc", "memory" - ); - return carry; -} -#define asm_add 1 - -static uint32_t vli_sub(uint32_t *result, const uint32_t *left, const uint32_t *right) { - uint32_t carry = 0; - uint32_t left_word; - uint32_t right_word; - - __asm__ volatile ( - ".syntax unified \n\t" - "ldmia %[lptr]!, {%[left]} \n\t" /* Load left word. */ - "ldmia %[rptr]!, {%[right]} \n\t" /* Load right word. */ - "subs %[left], %[right] \n\t" /* Subtract. */ - "stmia %[dptr]!, {%[left]} \n\t" /* Store result word. */ - - /* Now we just do the remaining words with the carry bit (using SBC) */ - REPEAT(DEC(uECC_WORDS), - "ldmia %[lptr]!, {%[left]} \n\t" - "ldmia %[rptr]!, {%[right]} \n\t" - "sbcs %[left], %[right] \n\t" - "stmia %[dptr]!, {%[left]} \n\t") - - "adcs %[carry], %[carry] \n\t" /* Store carry bit. */ - #if (uECC_PLATFORM != uECC_arm_thumb2) - ".syntax divided \n\t" - #endif - #if (uECC_PLATFORM == uECC_arm_thumb) - : [dptr] "+l" (result), [lptr] "+l" (left), [rptr] "+l" (right), - [carry] "+l" (carry), [left] "=l" (left_word), [right] "=l" (right_word) - #else - : [dptr] "+r" (result), [lptr] "+r" (left), [rptr] "+r" (right), - [carry] "+r" (carry), [left] "=r" (left_word), [right] "=r" (right_word) - #endif - : - : "cc", "memory" - ); - return !carry; // note that on ARM, carry flag set means "no borrow" when subtracting - // (for some reason...) -} -#define asm_sub 1 - -#if (uECC_PLATFORM != uECC_arm_thumb) -#if (uECC_WORDS == 5) -static void vli_mult(uint32_t *result, const uint32_t *left, const uint32_t *right) { - register uint32_t *r0 __asm__("r0") = result; - register const uint32_t *r1 __asm__("r1") = left; - register const uint32_t *r2 __asm__("r2") = right; - - __asm__ volatile ( - ".syntax unified \n\t" - "add r0, 12 \n\t" - "add r2, 12 \n\t" - "ldmia r1!, {r3,r4} \n\t" - "ldmia r2!, {r6,r7} \n\t" - - "umull r11, r12, r3, r6 \n\t" - "stmia r0!, {r11} \n\t" - - "mov r10, #0 \n\t" - "umull r11, r9, r3, r7 \n\t" - "adds r12, r11 \n\t" - "adc r9, #0 \n\t" - "umull r11, r14, r4, r6 \n\t" - "adds r12, r11 \n\t" - "adcs r9, r14 \n\t" - "adc r10, #0 \n\t" - "stmia r0!, {r12} \n\t" - - "umull r12, r14, r4, r7 \n\t" - "adds r9, r12 \n\t" - "adc r10, r14 \n\t" - "stmia r0!, {r9, r10} \n\t" - - "sub r0, 28 \n\t" - "sub r2, 20 \n\t" - "ldmia r2!, {r6,r7,r8} \n\t" - "ldmia r1!, {r5} \n\t" - - "umull r11, r12, r3, r6 \n\t" - "stmia r0!, {r11} \n\t" - - "mov r10, #0 \n\t" - "umull r11, r9, r3, r7 \n\t" - "adds r12, r11 \n\t" - "adc r9, #0 \n\t" - "umull r11, r14, r4, r6 \n\t" - "adds r12, r11 \n\t" - "adcs r9, r14 \n\t" - "adc r10, #0 \n\t" - "stmia r0!, {r12} \n\t" - - "mov r11, #0 \n\t" - "umull r12, r14, r3, r8 \n\t" - "adds r9, r12 \n\t" - "adcs r10, r14 \n\t" - "adc r11, #0 \n\t" - "umull r12, r14, r4, r7 \n\t" - "adds r9, r12 \n\t" - "adcs r10, r14 \n\t" - "adc r11, #0 \n\t" - "umull r12, r14, r5, r6 \n\t" - "adds r9, r12 \n\t" - "adcs r10, r14 \n\t" - "adc r11, #0 \n\t" - "stmia r0!, {r9} \n\t" - - "ldmia r1!, {r3} \n\t" - "mov r12, #0 \n\t" - "umull r14, r9, r4, r8 \n\t" - "adds r10, r14 \n\t" - "adcs r11, r9 \n\t" - "adc r12, #0 \n\t" - "umull r14, r9, r5, r7 \n\t" - "adds r10, r14 \n\t" - "adcs r11, r9 \n\t" - "adc r12, #0 \n\t" - "umull r14, r9, r3, r6 \n\t" - "adds r10, r14 \n\t" - "adcs r11, r9 \n\t" - "adc r12, #0 \n\t" - "ldr r14, [r0] \n\t" - "adds r10, r14 \n\t" - "adcs r11, #0 \n\t" - "adc r12, #0 \n\t" - "stmia r0!, {r10} \n\t" - - "ldmia r1!, {r4} \n\t" - "mov r14, #0 \n\t" - "umull r9, r10, r5, r8 \n\t" - "adds r11, r9 \n\t" - "adcs r12, r10 \n\t" - "adc r14, #0 \n\t" - "umull r9, r10, r3, r7 \n\t" - "adds r11, r9 \n\t" - "adcs r12, r10 \n\t" - "adc r14, #0 \n\t" - "umull r9, r10, r4, r6 \n\t" - "adds r11, r9 \n\t" - "adcs r12, r10 \n\t" - "adc r14, #0 \n\t" - "ldr r9, [r0] \n\t" - "adds r11, r9 \n\t" - "adcs r12, #0 \n\t" - "adc r14, #0 \n\t" - "stmia r0!, {r11} \n\t" - - "ldmia r2!, {r6} \n\t" - "mov r9, #0 \n\t" - "umull r10, r11, r5, r6 \n\t" - "adds r12, r10 \n\t" - "adcs r14, r11 \n\t" - "adc r9, #0 \n\t" - "umull r10, r11, r3, r8 \n\t" - "adds r12, r10 \n\t" - "adcs r14, r11 \n\t" - "adc r9, #0 \n\t" - "umull r10, r11, r4, r7 \n\t" - "adds r12, r10 \n\t" - "adcs r14, r11 \n\t" - "adc r9, #0 \n\t" - "ldr r10, [r0] \n\t" - "adds r12, r10 \n\t" - "adcs r14, #0 \n\t" - "adc r9, #0 \n\t" - "stmia r0!, {r12} \n\t" - - "ldmia r2!, {r7} \n\t" - "mov r10, #0 \n\t" - "umull r11, r12, r5, r7 \n\t" - "adds r14, r11 \n\t" - "adcs r9, r12 \n\t" - "adc r10, #0 \n\t" - "umull r11, r12, r3, r6 \n\t" - "adds r14, r11 \n\t" - "adcs r9, r12 \n\t" - "adc r10, #0 \n\t" - "umull r11, r12, r4, r8 \n\t" - "adds r14, r11 \n\t" - "adcs r9, r12 \n\t" - "adc r10, #0 \n\t" - "ldr r11, [r0] \n\t" - "adds r14, r11 \n\t" - "adcs r9, #0 \n\t" - "adc r10, #0 \n\t" - "stmia r0!, {r14} \n\t" - - "mov r11, #0 \n\t" - "umull r12, r14, r3, r7 \n\t" - "adds r9, r12 \n\t" - "adcs r10, r14 \n\t" - "adc r11, #0 \n\t" - "umull r12, r14, r4, r6 \n\t" - "adds r9, r12 \n\t" - "adcs r10, r14 \n\t" - "adc r11, #0 \n\t" - "stmia r0!, {r9} \n\t" - - "umull r14, r9, r4, r7 \n\t" - "adds r10, r14 \n\t" - "adc r11, r9 \n\t" - "stmia r0!, {r10, r11} \n\t" - #if (uECC_PLATFORM != uECC_arm_thumb2) - ".syntax divided \n\t" - #endif - : "+r" (r0), "+r" (r1), "+r" (r2) - : - : "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory" - ); -} -#define asm_mult 1 -#endif /* (uECC_WORDS == 5) */ - -#if (uECC_WORDS == 6) -static void vli_mult(uint32_t *result, const uint32_t *left, const uint32_t *right) { - register uint32_t *r0 __asm__("r0") = result; - register const uint32_t *r1 __asm__("r1") = left; - register const uint32_t *r2 __asm__("r2") = right; - - __asm__ volatile ( - ".syntax unified \n\t" - "add r0, 12 \n\t" - "add r2, 12 \n\t" - "ldmia r1!, {r3,r4,r5} \n\t" - "ldmia r2!, {r6,r7,r8} \n\t" - - "umull r11, r12, r3, r6 \n\t" - "stmia r0!, {r11} \n\t" - - "mov r10, #0 \n\t" - "umull r11, r9, r3, r7 \n\t" - "adds r12, r11 \n\t" - "adc r9, #0 \n\t" - "umull r11, r14, r4, r6 \n\t" - "adds r12, r11 \n\t" - "adcs r9, r14 \n\t" - "adc r10, #0 \n\t" - "stmia r0!, {r12} \n\t" - - "mov r11, #0 \n\t" - "umull r12, r14, r3, r8 \n\t" - "adds r9, r12 \n\t" - "adcs r10, r14 \n\t" - "adc r11, #0 \n\t" - "umull r12, r14, r4, r7 \n\t" - "adds r9, r12 \n\t" - "adcs r10, r14 \n\t" - "adc r11, #0 \n\t" - "umull r12, r14, r5, r6 \n\t" - "adds r9, r12 \n\t" - "adcs r10, r14 \n\t" - "adc r11, #0 \n\t" - "stmia r0!, {r9} \n\t" - - "mov r12, #0 \n\t" - "umull r14, r9, r4, r8 \n\t" - "adds r10, r14 \n\t" - "adcs r11, r9 \n\t" - "adc r12, #0 \n\t" - "umull r14, r9, r5, r7 \n\t" - "adds r10, r14 \n\t" - "adcs r11, r9 \n\t" - "adc r12, #0 \n\t" - "stmia r0!, {r10} \n\t" - - "umull r9, r10, r5, r8 \n\t" - "adds r11, r9 \n\t" - "adc r12, r10 \n\t" - "stmia r0!, {r11, r12} \n\t" - - "sub r0, 36 \n\t" - "sub r2, 24 \n\t" - "ldmia r2!, {r6,r7,r8} \n\t" - - "umull r11, r12, r3, r6 \n\t" - "stmia r0!, {r11} \n\t" - - "mov r10, #0 \n\t" - "umull r11, r9, r3, r7 \n\t" - "adds r12, r11 \n\t" - "adc r9, #0 \n\t" - "umull r11, r14, r4, r6 \n\t" - "adds r12, r11 \n\t" - "adcs r9, r14 \n\t" - "adc r10, #0 \n\t" - "stmia r0!, {r12} \n\t" - - "mov r11, #0 \n\t" - "umull r12, r14, r3, r8 \n\t" - "adds r9, r12 \n\t" - "adcs r10, r14 \n\t" - "adc r11, #0 \n\t" - "umull r12, r14, r4, r7 \n\t" - "adds r9, r12 \n\t" - "adcs r10, r14 \n\t" - "adc r11, #0 \n\t" - "umull r12, r14, r5, r6 \n\t" - "adds r9, r12 \n\t" - "adcs r10, r14 \n\t" - "adc r11, #0 \n\t" - "stmia r0!, {r9} \n\t" - - "ldmia r1!, {r3} \n\t" - "mov r12, #0 \n\t" - "umull r14, r9, r4, r8 \n\t" - "adds r10, r14 \n\t" - "adcs r11, r9 \n\t" - "adc r12, #0 \n\t" - "umull r14, r9, r5, r7 \n\t" - "adds r10, r14 \n\t" - "adcs r11, r9 \n\t" - "adc r12, #0 \n\t" - "umull r14, r9, r3, r6 \n\t" - "adds r10, r14 \n\t" - "adcs r11, r9 \n\t" - "adc r12, #0 \n\t" - "ldr r14, [r0] \n\t" - "adds r10, r14 \n\t" - "adcs r11, #0 \n\t" - "adc r12, #0 \n\t" - "stmia r0!, {r10} \n\t" - - "ldmia r1!, {r4} \n\t" - "mov r14, #0 \n\t" - "umull r9, r10, r5, r8 \n\t" - "adds r11, r9 \n\t" - "adcs r12, r10 \n\t" - "adc r14, #0 \n\t" - "umull r9, r10, r3, r7 \n\t" - "adds r11, r9 \n\t" - "adcs r12, r10 \n\t" - "adc r14, #0 \n\t" - "umull r9, r10, r4, r6 \n\t" - "adds r11, r9 \n\t" - "adcs r12, r10 \n\t" - "adc r14, #0 \n\t" - "ldr r9, [r0] \n\t" - "adds r11, r9 \n\t" - "adcs r12, #0 \n\t" - "adc r14, #0 \n\t" - "stmia r0!, {r11} \n\t" - - "ldmia r1!, {r5} \n\t" - "mov r9, #0 \n\t" - "umull r10, r11, r3, r8 \n\t" - "adds r12, r10 \n\t" - "adcs r14, r11 \n\t" - "adc r9, #0 \n\t" - "umull r10, r11, r4, r7 \n\t" - "adds r12, r10 \n\t" - "adcs r14, r11 \n\t" - "adc r9, #0 \n\t" - "umull r10, r11, r5, r6 \n\t" - "adds r12, r10 \n\t" - "adcs r14, r11 \n\t" - "adc r9, #0 \n\t" - "ldr r10, [r0] \n\t" - "adds r12, r10 \n\t" - "adcs r14, #0 \n\t" - "adc r9, #0 \n\t" - "stmia r0!, {r12} \n\t" - - "ldmia r2!, {r6} \n\t" - "mov r10, #0 \n\t" - "umull r11, r12, r3, r6 \n\t" - "adds r14, r11 \n\t" - "adcs r9, r12 \n\t" - "adc r10, #0 \n\t" - "umull r11, r12, r4, r8 \n\t" - "adds r14, r11 \n\t" - "adcs r9, r12 \n\t" - "adc r10, #0 \n\t" - "umull r11, r12, r5, r7 \n\t" - "adds r14, r11 \n\t" - "adcs r9, r12 \n\t" - "adc r10, #0 \n\t" - "ldr r11, [r0] \n\t" - "adds r14, r11 \n\t" - "adcs r9, #0 \n\t" - "adc r10, #0 \n\t" - "stmia r0!, {r14} \n\t" - - "ldmia r2!, {r7} \n\t" - "mov r11, #0 \n\t" - "umull r12, r14, r3, r7 \n\t" - "adds r9, r12 \n\t" - "adcs r10, r14 \n\t" - "adc r11, #0 \n\t" - "umull r12, r14, r4, r6 \n\t" - "adds r9, r12 \n\t" - "adcs r10, r14 \n\t" - "adc r11, #0 \n\t" - "umull r12, r14, r5, r8 \n\t" - "adds r9, r12 \n\t" - "adcs r10, r14 \n\t" - "adc r11, #0 \n\t" - "ldr r12, [r0] \n\t" - "adds r9, r12 \n\t" - "adcs r10, #0 \n\t" - "adc r11, #0 \n\t" - "stmia r0!, {r9} \n\t" - - "ldmia r2!, {r8} \n\t" - "mov r12, #0 \n\t" - "umull r14, r9, r3, r8 \n\t" - "adds r10, r14 \n\t" - "adcs r11, r9 \n\t" - "adc r12, #0 \n\t" - "umull r14, r9, r4, r7 \n\t" - "adds r10, r14 \n\t" - "adcs r11, r9 \n\t" - "adc r12, #0 \n\t" - "umull r14, r9, r5, r6 \n\t" - "adds r10, r14 \n\t" - "adcs r11, r9 \n\t" - "adc r12, #0 \n\t" - "ldr r14, [r0] \n\t" - "adds r10, r14 \n\t" - "adcs r11, #0 \n\t" - "adc r12, #0 \n\t" - "stmia r0!, {r10} \n\t" - - "mov r14, #0 \n\t" - "umull r9, r10, r4, r8 \n\t" - "adds r11, r9 \n\t" - "adcs r12, r10 \n\t" - "adc r14, #0 \n\t" - "umull r9, r10, r5, r7 \n\t" - "adds r11, r9 \n\t" - "adcs r12, r10 \n\t" - "adc r14, #0 \n\t" - "stmia r0!, {r11} \n\t" - - "umull r10, r11, r5, r8 \n\t" - "adds r12, r10 \n\t" - "adc r14, r11 \n\t" - "stmia r0!, {r12, r14} \n\t" - #if (uECC_PLATFORM != uECC_arm_thumb2) - ".syntax divided \n\t" - #endif - : "+r" (r0), "+r" (r1), "+r" (r2) - : - : "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory" - ); -} -#define asm_mult 1 -#endif /* (uECC_WORDS == 6) */ - -#if (uECC_WORDS == 7) -static void vli_mult(uint32_t *result, const uint32_t *left, const uint32_t *right) { - register uint32_t *r0 __asm__("r0") = result; - register const uint32_t *r1 __asm__("r1") = left; - register const uint32_t *r2 __asm__("r2") = right; - - __asm__ volatile ( - ".syntax unified \n\t" - "add r0, 24 \n\t" - "add r2, 24 \n\t" - "ldmia r1!, {r3} \n\t" - "ldmia r2!, {r6} \n\t" - - "umull r9, r10, r3, r6 \n\t" - "stmia r0!, {r9, r10} \n\t" - - "sub r0, 20 \n\t" - "sub r2, 16 \n\t" - "ldmia r2!, {r6, r7, r8} \n\t" - "ldmia r1!, {r4, r5} \n\t" - - "umull r9, r10, r3, r6 \n\t" - "stmia r0!, {r9} \n\t" - - "mov r14, #0 \n\t" - "umull r9, r12, r3, r7 \n\t" - "adds r10, r9 \n\t" - "adc r12, #0 \n\t" - "umull r9, r11, r4, r6 \n\t" - "adds r10, r9 \n\t" - "adcs r12, r11 \n\t" - "adc r14, #0 \n\t" - "stmia r0!, {r10} \n\t" - - "mov r9, #0 \n\t" - "umull r10, r11, r3, r8 \n\t" - "adds r12, r10 \n\t" - "adcs r14, r11 \n\t" - "adc r9, #0 \n\t" - "umull r10, r11, r4, r7 \n\t" - "adds r12, r10 \n\t" - "adcs r14, r11 \n\t" - "adc r9, #0 \n\t" - "umull r10, r11, r5, r6 \n\t" - "adds r12, r10 \n\t" - "adcs r14, r11 \n\t" - "adc r9, #0 \n\t" - "stmia r0!, {r12} \n\t" - - "ldmia r1!, {r3} \n\t" - "mov r10, #0 \n\t" - "umull r11, r12, r4, r8 \n\t" - "adds r14, r11 \n\t" - "adcs r9, r12 \n\t" - "adc r10, #0 \n\t" - "umull r11, r12, r5, r7 \n\t" - "adds r14, r11 \n\t" - "adcs r9, r12 \n\t" - "adc r10, #0 \n\t" - "umull r11, r12, r3, r6 \n\t" - "adds r14, r11 \n\t" - "adcs r9, r12 \n\t" - "adc r10, #0 \n\t" - "ldr r11, [r0] \n\t" - "adds r14, r11 \n\t" - "adcs r9, #0 \n\t" - "adc r10, #0 \n\t" - "stmia r0!, {r14} \n\t" - - "ldmia r2!, {r6} \n\t" - "mov r11, #0 \n\t" - "umull r12, r14, r4, r6 \n\t" - "adds r9, r12 \n\t" - "adcs r10, r14 \n\t" - "adc r11, #0 \n\t" - "umull r12, r14, r5, r8 \n\t" - "adds r9, r12 \n\t" - "adcs r10, r14 \n\t" - "adc r11, #0 \n\t" - "umull r12, r14, r3, r7 \n\t" - "adds r9, r12 \n\t" - "adcs r10, r14 \n\t" - "adc r11, #0 \n\t" - "ldr r12, [r0] \n\t" - "adds r9, r12 \n\t" - "adcs r10, #0 \n\t" - "adc r11, #0 \n\t" - "stmia r0!, {r9} \n\t" - - "mov r12, #0 \n\t" - "umull r14, r9, r5, r6 \n\t" - "adds r10, r14 \n\t" - "adcs r11, r9 \n\t" - "adc r12, #0 \n\t" - "umull r14, r9, r3, r8 \n\t" - "adds r10, r14 \n\t" - "adcs r11, r9 \n\t" - "adc r12, #0 \n\t" - "stmia r0!, {r10} \n\t" - - "umull r9, r10, r3, r6 \n\t" - "adds r11, r9 \n\t" - "adc r12, r10 \n\t" - "stmia r0!, {r11, r12} \n\t" - - "sub r0, 44 \n\t" - "sub r1, 16 \n\t" - "sub r2, 28 \n\t" - "ldmia r1!, {r3,r4,r5} \n\t" - "ldmia r2!, {r6,r7,r8} \n\t" - - "umull r9, r10, r3, r6 \n\t" - "stmia r0!, {r9} \n\t" - - "mov r14, #0 \n\t" - "umull r9, r12, r3, r7 \n\t" - "adds r10, r9 \n\t" - "adc r12, #0 \n\t" - "umull r9, r11, r4, r6 \n\t" - "adds r10, r9 \n\t" - "adcs r12, r11 \n\t" - "adc r14, #0 \n\t" - "stmia r0!, {r10} \n\t" - - "mov r9, #0 \n\t" - "umull r10, r11, r3, r8 \n\t" - "adds r12, r10 \n\t" - "adcs r14, r11 \n\t" - "adc r9, #0 \n\t" - "umull r10, r11, r4, r7 \n\t" - "adds r12, r10 \n\t" - "adcs r14, r11 \n\t" - "adc r9, #0 \n\t" - "umull r10, r11, r5, r6 \n\t" - "adds r12, r10 \n\t" - "adcs r14, r11 \n\t" - "adc r9, #0 \n\t" - "stmia r0!, {r12} \n\t" - - "ldmia r1!, {r3} \n\t" - "mov r10, #0 \n\t" - "umull r11, r12, r4, r8 \n\t" - "adds r14, r11 \n\t" - "adcs r9, r12 \n\t" - "adc r10, #0 \n\t" - "umull r11, r12, r5, r7 \n\t" - "adds r14, r11 \n\t" - "adcs r9, r12 \n\t" - "adc r10, #0 \n\t" - "umull r11, r12, r3, r6 \n\t" - "adds r14, r11 \n\t" - "adcs r9, r12 \n\t" - "adc r10, #0 \n\t" - "ldr r11, [r0] \n\t" - "adds r14, r11 \n\t" - "adcs r9, #0 \n\t" - "adc r10, #0 \n\t" - "stmia r0!, {r14} \n\t" - - "ldmia r1!, {r4} \n\t" - "mov r11, #0 \n\t" - "umull r12, r14, r5, r8 \n\t" - "adds r9, r12 \n\t" - "adcs r10, r14 \n\t" - "adc r11, #0 \n\t" - "umull r12, r14, r3, r7 \n\t" - "adds r9, r12 \n\t" - "adcs r10, r14 \n\t" - "adc r11, #0 \n\t" - "umull r12, r14, r4, r6 \n\t" - "adds r9, r12 \n\t" - "adcs r10, r14 \n\t" - "adc r11, #0 \n\t" - "ldr r12, [r0] \n\t" - "adds r9, r12 \n\t" - "adcs r10, #0 \n\t" - "adc r11, #0 \n\t" - "stmia r0!, {r9} \n\t" - - "ldmia r1!, {r5} \n\t" - "mov r12, #0 \n\t" - "umull r14, r9, r3, r8 \n\t" - "adds r10, r14 \n\t" - "adcs r11, r9 \n\t" - "adc r12, #0 \n\t" - "umull r14, r9, r4, r7 \n\t" - "adds r10, r14 \n\t" - "adcs r11, r9 \n\t" - "adc r12, #0 \n\t" - "umull r14, r9, r5, r6 \n\t" - "adds r10, r14 \n\t" - "adcs r11, r9 \n\t" - "adc r12, #0 \n\t" - "ldr r14, [r0] \n\t" - "adds r10, r14 \n\t" - "adcs r11, #0 \n\t" - "adc r12, #0 \n\t" - "stmia r0!, {r10} \n\t" - - "ldmia r1!, {r3} \n\t" - "mov r14, #0 \n\t" - "umull r9, r10, r4, r8 \n\t" - "adds r11, r9 \n\t" - "adcs r12, r10 \n\t" - "adc r14, #0 \n\t" - "umull r9, r10, r5, r7 \n\t" - "adds r11, r9 \n\t" - "adcs r12, r10 \n\t" - "adc r14, #0 \n\t" - "umull r9, r10, r3, r6 \n\t" - "adds r11, r9 \n\t" - "adcs r12, r10 \n\t" - "adc r14, #0 \n\t" - "ldr r9, [r0] \n\t" - "adds r11, r9 \n\t" - "adcs r12, #0 \n\t" - "adc r14, #0 \n\t" - "stmia r0!, {r11} \n\t" - - "ldmia r2!, {r6} \n\t" - "mov r9, #0 \n\t" - "umull r10, r11, r4, r6 \n\t" - "adds r12, r10 \n\t" - "adcs r14, r11 \n\t" - "adc r9, #0 \n\t" - "umull r10, r11, r5, r8 \n\t" - "adds r12, r10 \n\t" - "adcs r14, r11 \n\t" - "adc r9, #0 \n\t" - "umull r10, r11, r3, r7 \n\t" - "adds r12, r10 \n\t" - "adcs r14, r11 \n\t" - "adc r9, #0 \n\t" - "ldr r10, [r0] \n\t" - "adds r12, r10 \n\t" - "adcs r14, #0 \n\t" - "adc r9, #0 \n\t" - "stmia r0!, {r12} \n\t" - - "ldmia r2!, {r7} \n\t" - "mov r10, #0 \n\t" - "umull r11, r12, r4, r7 \n\t" - "adds r14, r11 \n\t" - "adcs r9, r12 \n\t" - "adc r10, #0 \n\t" - "umull r11, r12, r5, r6 \n\t" - "adds r14, r11 \n\t" - "adcs r9, r12 \n\t" - "adc r10, #0 \n\t" - "umull r11, r12, r3, r8 \n\t" - "adds r14, r11 \n\t" - "adcs r9, r12 \n\t" - "adc r10, #0 \n\t" - "ldr r11, [r0] \n\t" - "adds r14, r11 \n\t" - "adcs r9, #0 \n\t" - "adc r10, #0 \n\t" - "stmia r0!, {r14} \n\t" - - "ldmia r2!, {r8} \n\t" - "mov r11, #0 \n\t" - "umull r12, r14, r4, r8 \n\t" - "adds r9, r12 \n\t" - "adcs r10, r14 \n\t" - "adc r11, #0 \n\t" - "umull r12, r14, r5, r7 \n\t" - "adds r9, r12 \n\t" - "adcs r10, r14 \n\t" - "adc r11, #0 \n\t" - "umull r12, r14, r3, r6 \n\t" - "adds r9, r12 \n\t" - "adcs r10, r14 \n\t" - "adc r11, #0 \n\t" - "ldr r12, [r0] \n\t" - "adds r9, r12 \n\t" - "adcs r10, #0 \n\t" - "adc r11, #0 \n\t" - "stmia r0!, {r9} \n\t" - - "ldmia r2!, {r6} \n\t" - "mov r12, #0 \n\t" - "umull r14, r9, r4, r6 \n\t" - "adds r10, r14 \n\t" - "adcs r11, r9 \n\t" - "adc r12, #0 \n\t" - "umull r14, r9, r5, r8 \n\t" - "adds r10, r14 \n\t" - "adcs r11, r9 \n\t" - "adc r12, #0 \n\t" - "umull r14, r9, r3, r7 \n\t" - "adds r10, r14 \n\t" - "adcs r11, r9 \n\t" - "adc r12, #0 \n\t" - "ldr r14, [r0] \n\t" - "adds r10, r14 \n\t" - "adcs r11, #0 \n\t" - "adc r12, #0 \n\t" - "stmia r0!, {r10} \n\t" - - "mov r14, #0 \n\t" - "umull r9, r10, r5, r6 \n\t" - "adds r11, r9 \n\t" - "adcs r12, r10 \n\t" - "adc r14, #0 \n\t" - "umull r9, r10, r3, r8 \n\t" - "adds r11, r9 \n\t" - "adcs r12, r10 \n\t" - "adc r14, #0 \n\t" - "stmia r0!, {r11} \n\t" - - "umull r10, r11, r3, r6 \n\t" - "adds r12, r10 \n\t" - "adc r14, r11 \n\t" - "stmia r0!, {r12, r14} \n\t" - #if (uECC_PLATFORM != uECC_arm_thumb2) - ".syntax divided \n\t" - #endif - : "+r" (r0), "+r" (r1), "+r" (r2) - : - : "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory" - ); -} -#define asm_mult 1 -#endif /* (uECC_WORDS == 7) */ - -#if (uECC_WORDS == 8) -static void vli_mult(uint32_t *result, const uint32_t *left, const uint32_t *right) { - register uint32_t *r0 __asm__("r0") = result; - register const uint32_t *r1 __asm__("r1") = left; - register const uint32_t *r2 __asm__("r2") = right; - - __asm__ volatile ( - ".syntax unified \n\t" - "add r0, 24 \n\t" - "add r2, 24 \n\t" - "ldmia r1!, {r3,r4} \n\t" - "ldmia r2!, {r6,r7} \n\t" - - "umull r11, r12, r3, r6 \n\t" - "stmia r0!, {r11} \n\t" - - "mov r10, #0 \n\t" - "umull r11, r9, r3, r7 \n\t" - "adds r12, r11 \n\t" - "adc r9, #0 \n\t" - "umull r11, r14, r4, r6 \n\t" - "adds r12, r11 \n\t" - "adcs r9, r14 \n\t" - "adc r10, #0 \n\t" - "stmia r0!, {r12} \n\t" - - "umull r12, r14, r4, r7 \n\t" - "adds r9, r12 \n\t" - "adc r10, r14 \n\t" - "stmia r0!, {r9, r10} \n\t" - - "sub r0, 28 \n\t" - "sub r2, 20 \n\t" - "ldmia r2!, {r6,r7,r8} \n\t" - "ldmia r1!, {r5} \n\t" - - "umull r11, r12, r3, r6 \n\t" - "stmia r0!, {r11} \n\t" - - "mov r10, #0 \n\t" - "umull r11, r9, r3, r7 \n\t" - "adds r12, r11 \n\t" - "adc r9, #0 \n\t" - "umull r11, r14, r4, r6 \n\t" - "adds r12, r11 \n\t" - "adcs r9, r14 \n\t" - "adc r10, #0 \n\t" - "stmia r0!, {r12} \n\t" - - "mov r11, #0 \n\t" - "umull r12, r14, r3, r8 \n\t" - "adds r9, r12 \n\t" - "adcs r10, r14 \n\t" - "adc r11, #0 \n\t" - "umull r12, r14, r4, r7 \n\t" - "adds r9, r12 \n\t" - "adcs r10, r14 \n\t" - "adc r11, #0 \n\t" - "umull r12, r14, r5, r6 \n\t" - "adds r9, r12 \n\t" - "adcs r10, r14 \n\t" - "adc r11, #0 \n\t" - "stmia r0!, {r9} \n\t" - - "ldmia r1!, {r3} \n\t" - "mov r12, #0 \n\t" - "umull r14, r9, r4, r8 \n\t" - "adds r10, r14 \n\t" - "adcs r11, r9 \n\t" - "adc r12, #0 \n\t" - "umull r14, r9, r5, r7 \n\t" - "adds r10, r14 \n\t" - "adcs r11, r9 \n\t" - "adc r12, #0 \n\t" - "umull r14, r9, r3, r6 \n\t" - "adds r10, r14 \n\t" - "adcs r11, r9 \n\t" - "adc r12, #0 \n\t" - "ldr r14, [r0] \n\t" - "adds r10, r14 \n\t" - "adcs r11, #0 \n\t" - "adc r12, #0 \n\t" - "stmia r0!, {r10} \n\t" - - "ldmia r1!, {r4} \n\t" - "mov r14, #0 \n\t" - "umull r9, r10, r5, r8 \n\t" - "adds r11, r9 \n\t" - "adcs r12, r10 \n\t" - "adc r14, #0 \n\t" - "umull r9, r10, r3, r7 \n\t" - "adds r11, r9 \n\t" - "adcs r12, r10 \n\t" - "adc r14, #0 \n\t" - "umull r9, r10, r4, r6 \n\t" - "adds r11, r9 \n\t" - "adcs r12, r10 \n\t" - "adc r14, #0 \n\t" - "ldr r9, [r0] \n\t" - "adds r11, r9 \n\t" - "adcs r12, #0 \n\t" - "adc r14, #0 \n\t" - "stmia r0!, {r11} \n\t" - - "ldmia r2!, {r6} \n\t" - "mov r9, #0 \n\t" - "umull r10, r11, r5, r6 \n\t" - "adds r12, r10 \n\t" - "adcs r14, r11 \n\t" - "adc r9, #0 \n\t" - "umull r10, r11, r3, r8 \n\t" - "adds r12, r10 \n\t" - "adcs r14, r11 \n\t" - "adc r9, #0 \n\t" - "umull r10, r11, r4, r7 \n\t" - "adds r12, r10 \n\t" - "adcs r14, r11 \n\t" - "adc r9, #0 \n\t" - "ldr r10, [r0] \n\t" - "adds r12, r10 \n\t" - "adcs r14, #0 \n\t" - "adc r9, #0 \n\t" - "stmia r0!, {r12} \n\t" - - "ldmia r2!, {r7} \n\t" - "mov r10, #0 \n\t" - "umull r11, r12, r5, r7 \n\t" - "adds r14, r11 \n\t" - "adcs r9, r12 \n\t" - "adc r10, #0 \n\t" - "umull r11, r12, r3, r6 \n\t" - "adds r14, r11 \n\t" - "adcs r9, r12 \n\t" - "adc r10, #0 \n\t" - "umull r11, r12, r4, r8 \n\t" - "adds r14, r11 \n\t" - "adcs r9, r12 \n\t" - "adc r10, #0 \n\t" - "ldr r11, [r0] \n\t" - "adds r14, r11 \n\t" - "adcs r9, #0 \n\t" - "adc r10, #0 \n\t" - "stmia r0!, {r14} \n\t" - - "mov r11, #0 \n\t" - "umull r12, r14, r3, r7 \n\t" - "adds r9, r12 \n\t" - "adcs r10, r14 \n\t" - "adc r11, #0 \n\t" - "umull r12, r14, r4, r6 \n\t" - "adds r9, r12 \n\t" - "adcs r10, r14 \n\t" - "adc r11, #0 \n\t" - "stmia r0!, {r9} \n\t" - - "umull r14, r9, r4, r7 \n\t" - "adds r10, r14 \n\t" - "adc r11, r9 \n\t" - "stmia r0!, {r10, r11} \n\t" - - "sub r0, 52 \n\t" - "sub r1, 20 \n\t" - "sub r2, 32 \n\t" - "ldmia r1!, {r3,r4,r5} \n\t" - "ldmia r2!, {r6,r7,r8} \n\t" - - "umull r11, r12, r3, r6 \n\t" - "stmia r0!, {r11} \n\t" - - "mov r10, #0 \n\t" - "umull r11, r9, r3, r7 \n\t" - "adds r12, r11 \n\t" - "adc r9, #0 \n\t" - "umull r11, r14, r4, r6 \n\t" - "adds r12, r11 \n\t" - "adcs r9, r14 \n\t" - "adc r10, #0 \n\t" - "stmia r0!, {r12} \n\t" - - "mov r11, #0 \n\t" - "umull r12, r14, r3, r8 \n\t" - "adds r9, r12 \n\t" - "adcs r10, r14 \n\t" - "adc r11, #0 \n\t" - "umull r12, r14, r4, r7 \n\t" - "adds r9, r12 \n\t" - "adcs r10, r14 \n\t" - "adc r11, #0 \n\t" - "umull r12, r14, r5, r6 \n\t" - "adds r9, r12 \n\t" - "adcs r10, r14 \n\t" - "adc r11, #0 \n\t" - "stmia r0!, {r9} \n\t" - - "ldmia r1!, {r3} \n\t" - "mov r12, #0 \n\t" - "umull r14, r9, r4, r8 \n\t" - "adds r10, r14 \n\t" - "adcs r11, r9 \n\t" - "adc r12, #0 \n\t" - "umull r14, r9, r5, r7 \n\t" - "adds r10, r14 \n\t" - "adcs r11, r9 \n\t" - "adc r12, #0 \n\t" - "umull r14, r9, r3, r6 \n\t" - "adds r10, r14 \n\t" - "adcs r11, r9 \n\t" - "adc r12, #0 \n\t" - "ldr r14, [r0] \n\t" - "adds r10, r14 \n\t" - "adcs r11, #0 \n\t" - "adc r12, #0 \n\t" - "stmia r0!, {r10} \n\t" - - "ldmia r1!, {r4} \n\t" - "mov r14, #0 \n\t" - "umull r9, r10, r5, r8 \n\t" - "adds r11, r9 \n\t" - "adcs r12, r10 \n\t" - "adc r14, #0 \n\t" - "umull r9, r10, r3, r7 \n\t" - "adds r11, r9 \n\t" - "adcs r12, r10 \n\t" - "adc r14, #0 \n\t" - "umull r9, r10, r4, r6 \n\t" - "adds r11, r9 \n\t" - "adcs r12, r10 \n\t" - "adc r14, #0 \n\t" - "ldr r9, [r0] \n\t" - "adds r11, r9 \n\t" - "adcs r12, #0 \n\t" - "adc r14, #0 \n\t" - "stmia r0!, {r11} \n\t" - - "ldmia r1!, {r5} \n\t" - "mov r9, #0 \n\t" - "umull r10, r11, r3, r8 \n\t" - "adds r12, r10 \n\t" - "adcs r14, r11 \n\t" - "adc r9, #0 \n\t" - "umull r10, r11, r4, r7 \n\t" - "adds r12, r10 \n\t" - "adcs r14, r11 \n\t" - "adc r9, #0 \n\t" - "umull r10, r11, r5, r6 \n\t" - "adds r12, r10 \n\t" - "adcs r14, r11 \n\t" - "adc r9, #0 \n\t" - "ldr r10, [r0] \n\t" - "adds r12, r10 \n\t" - "adcs r14, #0 \n\t" - "adc r9, #0 \n\t" - "stmia r0!, {r12} \n\t" - - "ldmia r1!, {r3} \n\t" - "mov r10, #0 \n\t" - "umull r11, r12, r4, r8 \n\t" - "adds r14, r11 \n\t" - "adcs r9, r12 \n\t" - "adc r10, #0 \n\t" - "umull r11, r12, r5, r7 \n\t" - "adds r14, r11 \n\t" - "adcs r9, r12 \n\t" - "adc r10, #0 \n\t" - "umull r11, r12, r3, r6 \n\t" - "adds r14, r11 \n\t" - "adcs r9, r12 \n\t" - "adc r10, #0 \n\t" - "ldr r11, [r0] \n\t" - "adds r14, r11 \n\t" - "adcs r9, #0 \n\t" - "adc r10, #0 \n\t" - "stmia r0!, {r14} \n\t" - - "ldmia r1!, {r4} \n\t" - "mov r11, #0 \n\t" - "umull r12, r14, r5, r8 \n\t" - "adds r9, r12 \n\t" - "adcs r10, r14 \n\t" - "adc r11, #0 \n\t" - "umull r12, r14, r3, r7 \n\t" - "adds r9, r12 \n\t" - "adcs r10, r14 \n\t" - "adc r11, #0 \n\t" - "umull r12, r14, r4, r6 \n\t" - "adds r9, r12 \n\t" - "adcs r10, r14 \n\t" - "adc r11, #0 \n\t" - "ldr r12, [r0] \n\t" - "adds r9, r12 \n\t" - "adcs r10, #0 \n\t" - "adc r11, #0 \n\t" - "stmia r0!, {r9} \n\t" - - "ldmia r2!, {r6} \n\t" - "mov r12, #0 \n\t" - "umull r14, r9, r5, r6 \n\t" - "adds r10, r14 \n\t" - "adcs r11, r9 \n\t" - "adc r12, #0 \n\t" - "umull r14, r9, r3, r8 \n\t" - "adds r10, r14 \n\t" - "adcs r11, r9 \n\t" - "adc r12, #0 \n\t" - "umull r14, r9, r4, r7 \n\t" - "adds r10, r14 \n\t" - "adcs r11, r9 \n\t" - "adc r12, #0 \n\t" - "ldr r14, [r0] \n\t" - "adds r10, r14 \n\t" - "adcs r11, #0 \n\t" - "adc r12, #0 \n\t" - "stmia r0!, {r10} \n\t" - - "ldmia r2!, {r7} \n\t" - "mov r14, #0 \n\t" - "umull r9, r10, r5, r7 \n\t" - "adds r11, r9 \n\t" - "adcs r12, r10 \n\t" - "adc r14, #0 \n\t" - "umull r9, r10, r3, r6 \n\t" - "adds r11, r9 \n\t" - "adcs r12, r10 \n\t" - "adc r14, #0 \n\t" - "umull r9, r10, r4, r8 \n\t" - "adds r11, r9 \n\t" - "adcs r12, r10 \n\t" - "adc r14, #0 \n\t" - "ldr r9, [r0] \n\t" - "adds r11, r9 \n\t" - "adcs r12, #0 \n\t" - "adc r14, #0 \n\t" - "stmia r0!, {r11} \n\t" - - "ldmia r2!, {r8} \n\t" - "mov r9, #0 \n\t" - "umull r10, r11, r5, r8 \n\t" - "adds r12, r10 \n\t" - "adcs r14, r11 \n\t" - "adc r9, #0 \n\t" - "umull r10, r11, r3, r7 \n\t" - "adds r12, r10 \n\t" - "adcs r14, r11 \n\t" - "adc r9, #0 \n\t" - "umull r10, r11, r4, r6 \n\t" - "adds r12, r10 \n\t" - "adcs r14, r11 \n\t" - "adc r9, #0 \n\t" - "ldr r10, [r0] \n\t" - "adds r12, r10 \n\t" - "adcs r14, #0 \n\t" - "adc r9, #0 \n\t" - "stmia r0!, {r12} \n\t" - - "ldmia r2!, {r6} \n\t" - "mov r10, #0 \n\t" - "umull r11, r12, r5, r6 \n\t" - "adds r14, r11 \n\t" - "adcs r9, r12 \n\t" - "adc r10, #0 \n\t" - "umull r11, r12, r3, r8 \n\t" - "adds r14, r11 \n\t" - "adcs r9, r12 \n\t" - "adc r10, #0 \n\t" - "umull r11, r12, r4, r7 \n\t" - "adds r14, r11 \n\t" - "adcs r9, r12 \n\t" - "adc r10, #0 \n\t" - "ldr r11, [r0] \n\t" - "adds r14, r11 \n\t" - "adcs r9, #0 \n\t" - "adc r10, #0 \n\t" - "stmia r0!, {r14} \n\t" - - "ldmia r2!, {r7} \n\t" - "mov r11, #0 \n\t" - "umull r12, r14, r5, r7 \n\t" - "adds r9, r12 \n\t" - "adcs r10, r14 \n\t" - "adc r11, #0 \n\t" - "umull r12, r14, r3, r6 \n\t" - "adds r9, r12 \n\t" - "adcs r10, r14 \n\t" - "adc r11, #0 \n\t" - "umull r12, r14, r4, r8 \n\t" - "adds r9, r12 \n\t" - "adcs r10, r14 \n\t" - "adc r11, #0 \n\t" - "ldr r12, [r0] \n\t" - "adds r9, r12 \n\t" - "adcs r10, #0 \n\t" - "adc r11, #0 \n\t" - "stmia r0!, {r9} \n\t" - - "mov r12, #0 \n\t" - "umull r14, r9, r3, r7 \n\t" - "adds r10, r14 \n\t" - "adcs r11, r9 \n\t" - "adc r12, #0 \n\t" - "umull r14, r9, r4, r6 \n\t" - "adds r10, r14 \n\t" - "adcs r11, r9 \n\t" - "adc r12, #0 \n\t" - "stmia r0!, {r10} \n\t" - - "umull r9, r10, r4, r7 \n\t" - "adds r11, r9 \n\t" - "adc r12, r10 \n\t" - "stmia r0!, {r11, r12} \n\t" - #if (uECC_PLATFORM != uECC_arm_thumb2) - ".syntax divided \n\t" - #endif - : "+r" (r0), "+r" (r1), "+r" (r2) - : - : "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory" - ); -} -#define asm_mult 1 -#endif /* (uECC_WORDS == 8) */ - -#if uECC_SQUARE_FUNC -#if (uECC_WORDS == 5) -static void vli_square(uint32_t *result, const uint32_t *left) { - register uint32_t *r0 __asm__("r0") = result; - register const uint32_t *r1 __asm__("r1") = left; - - __asm__ volatile ( - ".syntax unified \n\t" - "ldmia r1!, {r2,r3,r4,r5,r6} \n\t" - - "umull r11, r12, r2, r2 \n\t" - "stmia r0!, {r11} \n\t" - - "mov r9, #0 \n\t" - "umull r10, r11, r2, r3 \n\t" - "adds r12, r10 \n\t" - "adcs r8, r11, #0 \n\t" - "adc r9, #0 \n\t" - "adds r12, r10 \n\t" - "adcs r8, r11 \n\t" - "adc r9, #0 \n\t" - "stmia r0!, {r12} \n\t" - - "mov r10, #0 \n\t" - "umull r11, r12, r2, r4 \n\t" - "adds r11, r11 \n\t" - "adcs r12, r12 \n\t" - "adc r10, #0 \n\t" - "adds r8, r11 \n\t" - "adcs r9, r12 \n\t" - "adc r10, #0 \n\t" - "umull r11, r12, r3, r3 \n\t" - "adds r8, r11 \n\t" - "adcs r9, r12 \n\t" - "adc r10, #0 \n\t" - "stmia r0!, {r8} \n\t" - - "mov r12, #0 \n\t" - "umull r8, r11, r2, r5 \n\t" - "umull r1, r14, r3, r4 \n\t" - "adds r8, r1 \n\t" - "adcs r11, r14 \n\t" - "adc r12, #0 \n\t" - "adds r8, r8 \n\t" - "adcs r11, r11 \n\t" - "adc r12, r12 \n\t" - "adds r8, r9 \n\t" - "adcs r11, r10 \n\t" - "adc r12, #0 \n\t" - "stmia r0!, {r8} \n\t" - - "mov r10, #0 \n\t" - "umull r8, r9, r2, r6 \n\t" - "umull r1, r14, r3, r5 \n\t" - "adds r8, r1 \n\t" - "adcs r9, r14 \n\t" - "adc r10, #0 \n\t" - "adds r8, r8 \n\t" - "adcs r9, r9 \n\t" - "adc r10, r10 \n\t" - "umull r1, r14, r4, r4 \n\t" - "adds r8, r1 \n\t" - "adcs r9, r14 \n\t" - "adc r10, #0 \n\t" - "adds r8, r11 \n\t" - "adcs r9, r12 \n\t" - "adc r10, #0 \n\t" - "stmia r0!, {r8} \n\t" - - "mov r12, #0 \n\t" - "umull r8, r11, r3, r6 \n\t" - "umull r1, r14, r4, r5 \n\t" - "adds r8, r1 \n\t" - "adcs r11, r14 \n\t" - "adc r12, #0 \n\t" - "adds r8, r8 \n\t" - "adcs r11, r11 \n\t" - "adc r12, r12 \n\t" - "adds r8, r9 \n\t" - "adcs r11, r10 \n\t" - "adc r12, #0 \n\t" - "stmia r0!, {r8} \n\t" - - "mov r8, #0 \n\t" - "umull r1, r10, r4, r6 \n\t" - "adds r1, r1 \n\t" - "adcs r10, r10 \n\t" - "adc r8, #0 \n\t" - "adds r11, r1 \n\t" - "adcs r12, r10 \n\t" - "adc r8, #0 \n\t" - "umull r1, r10, r5, r5 \n\t" - "adds r11, r1 \n\t" - "adcs r12, r10 \n\t" - "adc r8, #0 \n\t" - "stmia r0!, {r11} \n\t" - - "mov r11, #0 \n\t" - "umull r1, r10, r5, r6 \n\t" - "adds r1, r1 \n\t" - "adcs r10, r10 \n\t" - "adc r11, #0 \n\t" - "adds r12, r1 \n\t" - "adcs r8, r10 \n\t" - "adc r11, #0 \n\t" - "stmia r0!, {r12} \n\t" - - "umull r1, r10, r6, r6 \n\t" - "adds r8, r1 \n\t" - "adcs r11, r10 \n\t" - "stmia r0!, {r8, r11} \n\t" - #if (uECC_PLATFORM != uECC_arm_thumb2) - ".syntax divided \n\t" - #endif - : "+r" (r0), "+r" (r1) - : - : "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory" - ); -} -#define asm_square 1 -#endif /* (uECC_WORDS == 5) */ - -#if (uECC_WORDS == 6) -static void vli_square(uint32_t *result, const uint32_t *left) { - register uint32_t *r0 __asm__("r0") = result; - register const uint32_t *r1 __asm__("r1") = left; - - __asm__ volatile ( - ".syntax unified \n\t" - "ldmia r1!, {r2,r3,r4,r5,r6,r7} \n\t" - - "umull r11, r12, r2, r2 \n\t" - "stmia r0!, {r11} \n\t" - - "mov r9, #0 \n\t" - "umull r10, r11, r2, r3 \n\t" - "adds r12, r10 \n\t" - "adcs r8, r11, #0 \n\t" - "adc r9, #0 \n\t" - "adds r12, r10 \n\t" - "adcs r8, r11 \n\t" - "adc r9, #0 \n\t" - "stmia r0!, {r12} \n\t" - - "mov r10, #0 \n\t" - "umull r11, r12, r2, r4 \n\t" - "adds r11, r11 \n\t" - "adcs r12, r12 \n\t" - "adc r10, #0 \n\t" - "adds r8, r11 \n\t" - "adcs r9, r12 \n\t" - "adc r10, #0 \n\t" - "umull r11, r12, r3, r3 \n\t" - "adds r8, r11 \n\t" - "adcs r9, r12 \n\t" - "adc r10, #0 \n\t" - "stmia r0!, {r8} \n\t" - - "mov r12, #0 \n\t" - "umull r8, r11, r2, r5 \n\t" - "umull r1, r14, r3, r4 \n\t" - "adds r8, r1 \n\t" - "adcs r11, r14 \n\t" - "adc r12, #0 \n\t" - "adds r8, r8 \n\t" - "adcs r11, r11 \n\t" - "adc r12, r12 \n\t" - "adds r8, r9 \n\t" - "adcs r11, r10 \n\t" - "adc r12, #0 \n\t" - "stmia r0!, {r8} \n\t" - - "mov r10, #0 \n\t" - "umull r8, r9, r2, r6 \n\t" - "umull r1, r14, r3, r5 \n\t" - "adds r8, r1 \n\t" - "adcs r9, r14 \n\t" - "adc r10, #0 \n\t" - "adds r8, r8 \n\t" - "adcs r9, r9 \n\t" - "adc r10, r10 \n\t" - "umull r1, r14, r4, r4 \n\t" - "adds r8, r1 \n\t" - "adcs r9, r14 \n\t" - "adc r10, #0 \n\t" - "adds r8, r11 \n\t" - "adcs r9, r12 \n\t" - "adc r10, #0 \n\t" - "stmia r0!, {r8} \n\t" - - "mov r12, #0 \n\t" - "umull r8, r11, r2, r7 \n\t" - "umull r1, r14, r3, r6 \n\t" - "adds r8, r1 \n\t" - "adcs r11, r14 \n\t" - "adc r12, #0 \n\t" - "umull r1, r14, r4, r5 \n\t" - "adds r8, r1 \n\t" - "adcs r11, r14 \n\t" - "adc r12, #0 \n\t" - "adds r8, r8 \n\t" - "adcs r11, r11 \n\t" - "adc r12, r12 \n\t" - "adds r8, r9 \n\t" - "adcs r11, r10 \n\t" - "adc r12, #0 \n\t" - "stmia r0!, {r8} \n\t" - - "mov r10, #0 \n\t" - "umull r8, r9, r3, r7 \n\t" - "umull r1, r14, r4, r6 \n\t" - "adds r8, r1 \n\t" - "adcs r9, r14 \n\t" - "adc r10, #0 \n\t" - "adds r8, r8 \n\t" - "adcs r9, r9 \n\t" - "adc r10, r10 \n\t" - "umull r1, r14, r5, r5 \n\t" - "adds r8, r1 \n\t" - "adcs r9, r14 \n\t" - "adc r10, #0 \n\t" - "adds r8, r11 \n\t" - "adcs r9, r12 \n\t" - "adc r10, #0 \n\t" - "stmia r0!, {r8} \n\t" - - "mov r12, #0 \n\t" - "umull r8, r11, r4, r7 \n\t" - "umull r1, r14, r5, r6 \n\t" - "adds r8, r1 \n\t" - "adcs r11, r14 \n\t" - "adc r12, #0 \n\t" - "adds r8, r8 \n\t" - "adcs r11, r11 \n\t" - "adc r12, r12 \n\t" - "adds r8, r9 \n\t" - "adcs r11, r10 \n\t" - "adc r12, #0 \n\t" - "stmia r0!, {r8} \n\t" - - "mov r8, #0 \n\t" - "umull r1, r10, r5, r7 \n\t" - "adds r1, r1 \n\t" - "adcs r10, r10 \n\t" - "adc r8, #0 \n\t" - "adds r11, r1 \n\t" - "adcs r12, r10 \n\t" - "adc r8, #0 \n\t" - "umull r1, r10, r6, r6 \n\t" - "adds r11, r1 \n\t" - "adcs r12, r10 \n\t" - "adc r8, #0 \n\t" - "stmia r0!, {r11} \n\t" - - "mov r11, #0 \n\t" - "umull r1, r10, r6, r7 \n\t" - "adds r1, r1 \n\t" - "adcs r10, r10 \n\t" - "adc r11, #0 \n\t" - "adds r12, r1 \n\t" - "adcs r8, r10 \n\t" - "adc r11, #0 \n\t" - "stmia r0!, {r12} \n\t" - - "umull r1, r10, r7, r7 \n\t" - "adds r8, r1 \n\t" - "adcs r11, r10 \n\t" - "stmia r0!, {r8, r11} \n\t" - #if (uECC_PLATFORM != uECC_arm_thumb2) - ".syntax divided \n\t" - #endif - : "+r" (r0), "+r" (r1) - : - : "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory" - ); -} -#define asm_square 1 -#endif /* (uECC_WORDS == 6) */ - -#if (uECC_WORDS == 7) -static void vli_square(uint32_t *result, const uint32_t *left) { - register uint32_t *r0 __asm__("r0") = result; - register const uint32_t *r1 __asm__("r1") = left; - - __asm__ volatile ( - ".syntax unified \n\t" - "ldmia r1!, {r2} \n\t" - "add r1, 20 \n\t" - "ldmia r1!, {r5} \n\t" - "add r0, 24 \n\t" - "umull r8, r9, r2, r5 \n\t" - "stmia r0!, {r8, r9} \n\t" - "sub r0, 32 \n\t" - "sub r1, 28 \n\t" - - "ldmia r1!, {r2, r3, r4, r5, r6, r7} \n\t" - - "umull r11, r12, r2, r2 \n\t" - "stmia r0!, {r11} \n\t" - - "mov r9, #0 \n\t" - "umull r10, r11, r2, r3 \n\t" - "adds r12, r10 \n\t" - "adcs r8, r11, #0 \n\t" - "adc r9, #0 \n\t" - "adds r12, r10 \n\t" - "adcs r8, r11 \n\t" - "adc r9, #0 \n\t" - "stmia r0!, {r12} \n\t" - - "mov r10, #0 \n\t" - "umull r11, r12, r2, r4 \n\t" - "adds r11, r11 \n\t" - "adcs r12, r12 \n\t" - "adc r10, #0 \n\t" - "adds r8, r11 \n\t" - "adcs r9, r12 \n\t" - "adc r10, #0 \n\t" - "umull r11, r12, r3, r3 \n\t" - "adds r8, r11 \n\t" - "adcs r9, r12 \n\t" - "adc r10, #0 \n\t" - "stmia r0!, {r8} \n\t" - - "mov r12, #0 \n\t" - "umull r8, r11, r2, r5 \n\t" - "mov r14, r11 \n\t" - "umlal r8, r11, r3, r4 \n\t" - "cmp r14, r11 \n\t" - "it hi \n\t" - "adchi r12, #0 \n\t" - "adds r8, r8 \n\t" - "adcs r11, r11 \n\t" - "adc r12, r12 \n\t" - "adds r8, r9 \n\t" - "adcs r11, r10 \n\t" - "adc r12, #0 \n\t" - "stmia r0!, {r8} \n\t" - - "mov r10, #0 \n\t" - "umull r8, r9, r2, r6 \n\t" - "mov r14, r9 \n\t" - "umlal r8, r9, r3, r5 \n\t" - "cmp r14, r9 \n\t" - "it hi \n\t" - "adchi r10, #0 \n\t" - "adds r8, r8 \n\t" - "adcs r9, r9 \n\t" - "adc r10, r10 \n\t" - "mov r14, r9 \n\t" - "umlal r8, r9, r4, r4 \n\t" - "cmp r14, r9 \n\t" - "it hi \n\t" - "adchi r10, #0 \n\t" - "adds r8, r11 \n\t" - "adcs r9, r12 \n\t" - "adc r10, #0 \n\t" - "stmia r0!, {r8} \n\t" - - "mov r12, #0 \n\t" - "umull r8, r11, r2, r7 \n\t" - "mov r14, r11 \n\t" - "umlal r8, r11, r3, r6 \n\t" - "cmp r14, r11 \n\t" - "it hi \n\t" - "adchi r12, #0 \n\t" - "mov r14, r11 \n\t" - "umlal r8, r11, r4, r5 \n\t" - "cmp r14, r11 \n\t" - "it hi \n\t" - "adchi r12, #0 \n\t" - "adds r8, r8 \n\t" - "adcs r11, r11 \n\t" - "adc r12, r12 \n\t" - "adds r8, r9 \n\t" - "adcs r11, r10 \n\t" - "adc r12, #0 \n\t" - "stmia r0!, {r8} \n\t" - - "ldmia r1!, {r2} \n\t" - "mov r10, #0 \n\t" - "umull r8, r9, r3, r7 \n\t" - "mov r14, r9 \n\t" - "umlal r8, r9, r4, r6 \n\t" - "cmp r14, r9 \n\t" - "it hi \n\t" - "adchi r10, #0 \n\t" - "ldr r14, [r0] \n\t" - "adds r8, r14 \n\t" - "adcs r9, #0 \n\t" - "adc r10, #0 \n\t" - "adds r8, r8 \n\t" - "adcs r9, r9 \n\t" - "adc r10, r10 \n\t" - "mov r14, r9 \n\t" - "umlal r8, r9, r5, r5 \n\t" - "cmp r14, r9 \n\t" - "it hi \n\t" - "adchi r10, #0 \n\t" - "adds r8, r11 \n\t" - "adcs r9, r12 \n\t" - "adc r10, #0 \n\t" - "stmia r0!, {r8} \n\t" - - "mov r12, #0 \n\t" - "umull r8, r11, r3, r2 \n\t" - "mov r14, r11 \n\t" - "umlal r8, r11, r4, r7 \n\t" - "cmp r14, r11 \n\t" - "it hi \n\t" - "adchi r12, #0 \n\t" - "mov r14, r11 \n\t" - "umlal r8, r11, r5, r6 \n\t" - "cmp r14, r11 \n\t" - "it hi \n\t" - "adchi r12, #0 \n\t" - "ldr r14, [r0] \n\t" - "adds r8, r14 \n\t" - "adcs r11, #0 \n\t" - "adc r12, #0 \n\t" - "adds r8, r8 \n\t" - "adcs r11, r11 \n\t" - "adc r12, r12 \n\t" - "adds r8, r9 \n\t" - "adcs r11, r10 \n\t" - "adc r12, #0 \n\t" - "stmia r0!, {r8} \n\t" - - "mov r10, #0 \n\t" - "umull r8, r9, r4, r2 \n\t" - "mov r14, r9 \n\t" - "umlal r8, r9, r5, r7 \n\t" - "cmp r14, r9 \n\t" - "it hi \n\t" - "adchi r10, #0 \n\t" - "adds r8, r8 \n\t" - "adcs r9, r9 \n\t" - "adc r10, r10 \n\t" - "mov r14, r9 \n\t" - "umlal r8, r9, r6, r6 \n\t" - "cmp r14, r9 \n\t" - "it hi \n\t" - "adchi r10, #0 \n\t" - "adds r8, r11 \n\t" - "adcs r9, r12 \n\t" - "adc r10, #0 \n\t" - "stmia r0!, {r8} \n\t" - - "mov r12, #0 \n\t" - "umull r8, r11, r5, r2 \n\t" - "mov r14, r11 \n\t" - "umlal r8, r11, r6, r7 \n\t" - "cmp r14, r11 \n\t" - "it hi \n\t" - "adchi r12, #0 \n\t" - "adds r8, r8 \n\t" - "adcs r11, r11 \n\t" - "adc r12, r12 \n\t" - "adds r8, r9 \n\t" - "adcs r11, r10 \n\t" - "adc r12, #0 \n\t" - "stmia r0!, {r8} \n\t" - - "mov r8, #0 \n\t" - "umull r1, r10, r6, r2 \n\t" - "adds r1, r1 \n\t" - "adcs r10, r10 \n\t" - "adc r8, #0 \n\t" - "adds r11, r1 \n\t" - "adcs r12, r10 \n\t" - "adc r8, #0 \n\t" - "umull r1, r10, r7, r7 \n\t" - "adds r11, r1 \n\t" - "adcs r12, r10 \n\t" - "adc r8, #0 \n\t" - "stmia r0!, {r11} \n\t" - - "mov r11, #0 \n\t" - "umull r1, r10, r7, r2 \n\t" - "adds r1, r1 \n\t" - "adcs r10, r10 \n\t" - "adc r11, #0 \n\t" - "adds r12, r1 \n\t" - "adcs r8, r10 \n\t" - "adc r11, #0 \n\t" - "stmia r0!, {r12} \n\t" - - "umull r1, r10, r2, r2 \n\t" - "adds r8, r1 \n\t" - "adcs r11, r10 \n\t" - "stmia r0!, {r8, r11} \n\t" - #if (uECC_PLATFORM != uECC_arm_thumb2) - ".syntax divided \n\t" - #endif - : "+r" (r0), "+r" (r1) - : - : "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory" - ); -} -#define asm_square 1 -#endif /* (uECC_WORDS == 7) */ - -#if (uECC_WORDS == 8) -static void vli_square(uint32_t *result, const uint32_t *left) { - register uint32_t *r0 __asm__("r0") = result; - register const uint32_t *r1 __asm__("r1") = left; - - __asm__ volatile ( - ".syntax unified \n\t" - "ldmia r1!, {r2, r3} \n\t" - "add r1, 16 \n\t" - "ldmia r1!, {r5, r6} \n\t" - "add r0, 24 \n\t" - - "umull r8, r9, r2, r5 \n\t" - "stmia r0!, {r8} \n\t" - - "umull r12, r10, r2, r6 \n\t" - "adds r9, r12 \n\t" - "adc r10, #0 \n\t" - "stmia r0!, {r9} \n\t" - - "umull r8, r9, r3, r6 \n\t" - "adds r10, r8 \n\t" - "adc r11, r9, #0 \n\t" - "stmia r0!, {r10, r11} \n\t" - - "sub r0, 40 \n\t" - "sub r1, 32 \n\t" - "ldmia r1!, {r2,r3,r4,r5,r6,r7} \n\t" - - "umull r11, r12, r2, r2 \n\t" - "stmia r0!, {r11} \n\t" - - "mov r9, #0 \n\t" - "umull r10, r11, r2, r3 \n\t" - "adds r12, r10 \n\t" - "adcs r8, r11, #0 \n\t" - "adc r9, #0 \n\t" - "adds r12, r10 \n\t" - "adcs r8, r11 \n\t" - "adc r9, #0 \n\t" - "stmia r0!, {r12} \n\t" - - "mov r10, #0 \n\t" - "umull r11, r12, r2, r4 \n\t" - "adds r11, r11 \n\t" - "adcs r12, r12 \n\t" - "adc r10, #0 \n\t" - "adds r8, r11 \n\t" - "adcs r9, r12 \n\t" - "adc r10, #0 \n\t" - "umull r11, r12, r3, r3 \n\t" - "adds r8, r11 \n\t" - "adcs r9, r12 \n\t" - "adc r10, #0 \n\t" - "stmia r0!, {r8} \n\t" - - "mov r12, #0 \n\t" - "umull r8, r11, r2, r5 \n\t" - "mov r14, r11 \n\t" - "umlal r8, r11, r3, r4 \n\t" - "cmp r14, r11 \n\t" - "it hi \n\t" - "adchi r12, #0 \n\t" - "adds r8, r8 \n\t" - "adcs r11, r11 \n\t" - "adc r12, r12 \n\t" - "adds r8, r9 \n\t" - "adcs r11, r10 \n\t" - "adc r12, #0 \n\t" - "stmia r0!, {r8} \n\t" - - "mov r10, #0 \n\t" - "umull r8, r9, r2, r6 \n\t" - "mov r14, r9 \n\t" - "umlal r8, r9, r3, r5 \n\t" - "cmp r14, r9 \n\t" - "it hi \n\t" - "adchi r10, #0 \n\t" - "adds r8, r8 \n\t" - "adcs r9, r9 \n\t" - "adc r10, r10 \n\t" - "mov r14, r9 \n\t" - "umlal r8, r9, r4, r4 \n\t" - "cmp r14, r9 \n\t" - "it hi \n\t" - "adchi r10, #0 \n\t" - "adds r8, r11 \n\t" - "adcs r9, r12 \n\t" - "adc r10, #0 \n\t" - "stmia r0!, {r8} \n\t" - - "mov r12, #0 \n\t" - "umull r8, r11, r2, r7 \n\t" - "mov r14, r11 \n\t" - "umlal r8, r11, r3, r6 \n\t" - "cmp r14, r11 \n\t" - "it hi \n\t" - "adchi r12, #0 \n\t" - "mov r14, r11 \n\t" - "umlal r8, r11, r4, r5 \n\t" - "cmp r14, r11 \n\t" - "it hi \n\t" - "adchi r12, #0 \n\t" - "adds r8, r8 \n\t" - "adcs r11, r11 \n\t" - "adc r12, r12 \n\t" - "adds r8, r9 \n\t" - "adcs r11, r10 \n\t" - "adc r12, #0 \n\t" - "stmia r0!, {r8} \n\t" - - "ldmia r1!, {r2} \n\t" - "mov r10, #0 \n\t" - "umull r8, r9, r3, r7 \n\t" - "mov r14, r9 \n\t" - "umlal r8, r9, r4, r6 \n\t" - "cmp r14, r9 \n\t" - "it hi \n\t" - "adchi r10, #0 \n\t" - "ldr r14, [r0] \n\t" - "adds r8, r14 \n\t" - "adcs r9, #0 \n\t" - "adc r10, #0 \n\t" - "adds r8, r8 \n\t" - "adcs r9, r9 \n\t" - "adc r10, r10 \n\t" - "mov r14, r9 \n\t" - "umlal r8, r9, r5, r5 \n\t" - "cmp r14, r9 \n\t" - "it hi \n\t" - "adchi r10, #0 \n\t" - "adds r8, r11 \n\t" - "adcs r9, r12 \n\t" - "adc r10, #0 \n\t" - "stmia r0!, {r8} \n\t" - - "mov r12, #0 \n\t" - "umull r8, r11, r3, r2 \n\t" - "mov r14, r11 \n\t" - "umlal r8, r11, r4, r7 \n\t" - "cmp r14, r11 \n\t" - "it hi \n\t" - "adchi r12, #0 \n\t" - "mov r14, r11 \n\t" - "umlal r8, r11, r5, r6 \n\t" - "cmp r14, r11 \n\t" - "it hi \n\t" - "adchi r12, #0 \n\t" - "ldr r14, [r0] \n\t" - "adds r8, r14 \n\t" - "adcs r11, #0 \n\t" - "adc r12, #0 \n\t" - "adds r8, r8 \n\t" - "adcs r11, r11 \n\t" - "adc r12, r12 \n\t" - "adds r8, r9 \n\t" - "adcs r11, r10 \n\t" - "adc r12, #0 \n\t" - "stmia r0!, {r8} \n\t" - - "ldmia r1!, {r3} \n\t" - "mov r10, #0 \n\t" - "umull r8, r9, r4, r2 \n\t" - "mov r14, r9 \n\t" - "umlal r8, r9, r5, r7 \n\t" - "cmp r14, r9 \n\t" - "it hi \n\t" - "adchi r10, #0 \n\t" - "ldr r14, [r0] \n\t" - "adds r8, r14 \n\t" - "adcs r9, #0 \n\t" - "adc r10, #0 \n\t" - "adds r8, r8 \n\t" - "adcs r9, r9 \n\t" - "adc r10, r10 \n\t" - "mov r14, r9 \n\t" - "umlal r8, r9, r6, r6 \n\t" - "cmp r14, r9 \n\t" - "it hi \n\t" - "adchi r10, #0 \n\t" - "adds r8, r11 \n\t" - "adcs r9, r12 \n\t" - "adc r10, #0 \n\t" - "stmia r0!, {r8} \n\t" - - "mov r12, #0 \n\t" - "umull r8, r11, r4, r3 \n\t" - "mov r14, r11 \n\t" - "umlal r8, r11, r5, r2 \n\t" - "cmp r14, r11 \n\t" - "it hi \n\t" - "adchi r12, #0 \n\t" - "mov r14, r11 \n\t" - "umlal r8, r11, r6, r7 \n\t" - "cmp r14, r11 \n\t" - "it hi \n\t" - "adchi r12, #0 \n\t" - "ldr r14, [r0] \n\t" - "adds r8, r14 \n\t" - "adcs r11, #0 \n\t" - "adc r12, #0 \n\t" - "adds r8, r8 \n\t" - "adcs r11, r11 \n\t" - "adc r12, r12 \n\t" - "adds r8, r9 \n\t" - "adcs r11, r10 \n\t" - "adc r12, #0 \n\t" - "stmia r0!, {r8} \n\t" - - "mov r10, #0 \n\t" - "umull r8, r9, r5, r3 \n\t" - "mov r14, r9 \n\t" - "umlal r8, r9, r6, r2 \n\t" - "cmp r14, r9 \n\t" - "it hi \n\t" - "adchi r10, #0 \n\t" - "adds r8, r8 \n\t" - "adcs r9, r9 \n\t" - "adc r10, r10 \n\t" - "mov r14, r9 \n\t" - "umlal r8, r9, r7, r7 \n\t" - "cmp r14, r9 \n\t" - "it hi \n\t" - "adchi r10, #0 \n\t" - "adds r8, r11 \n\t" - "adcs r9, r12 \n\t" - "adc r10, #0 \n\t" - "stmia r0!, {r8} \n\t" - - "mov r12, #0 \n\t" - "umull r8, r11, r6, r3 \n\t" - "mov r14, r11 \n\t" - "umlal r8, r11, r7, r2 \n\t" - "cmp r14, r11 \n\t" - "it hi \n\t" - "adchi r12, #0 \n\t" - "adds r8, r8 \n\t" - "adcs r11, r11 \n\t" - "adc r12, r12 \n\t" - "adds r8, r9 \n\t" - "adcs r11, r10 \n\t" - "adc r12, #0 \n\t" - "stmia r0!, {r8} \n\t" - - "mov r8, #0 \n\t" - "umull r1, r10, r7, r3 \n\t" - "adds r1, r1 \n\t" - "adcs r10, r10 \n\t" - "adc r8, #0 \n\t" - "adds r11, r1 \n\t" - "adcs r12, r10 \n\t" - "adc r8, #0 \n\t" - "umull r1, r10, r2, r2 \n\t" - "adds r11, r1 \n\t" - "adcs r12, r10 \n\t" - "adc r8, #0 \n\t" - "stmia r0!, {r11} \n\t" - - "mov r11, #0 \n\t" - "umull r1, r10, r2, r3 \n\t" - "adds r1, r1 \n\t" - "adcs r10, r10 \n\t" - "adc r11, #0 \n\t" - "adds r12, r1 \n\t" - "adcs r8, r10 \n\t" - "adc r11, #0 \n\t" - "stmia r0!, {r12} \n\t" - - "umull r1, r10, r3, r3 \n\t" - "adds r8, r1 \n\t" - "adcs r11, r10 \n\t" - "stmia r0!, {r8, r11} \n\t" - #if (uECC_PLATFORM != uECC_arm_thumb2) - ".syntax divided \n\t" - #endif - : "+r" (r0), "+r" (r1) - : - : "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory" - ); -} -#define asm_square 1 -#endif /* (uECC_WORDS == 8) */ -#endif /* uECC_SQUARE_FUNC */ - -#endif /* (uECC_PLATFORM != uECC_arm_thumb) */ -#endif /* (uECC_ASM == uECC_asm_fast) */ - -#if !asm_add -static uint32_t vli_add(uint32_t *result, const uint32_t *left, const uint32_t *right) { - uint32_t counter = uECC_WORDS; - uint32_t carry = 0; - uint32_t left_word; - uint32_t right_word; - - __asm__ volatile ( - ".syntax unified \n\t" - "1: \n\t" - "ldmia %[lptr]!, {%[left]} \n\t" /* Load left word. */ - "ldmia %[rptr]!, {%[right]} \n\t" /* Load right word. */ - "lsrs %[carry], #1 \n\t" /* Set up carry flag (carry = 0 after this). */ - "adcs %[left], %[right] \n\t" /* Add with carry. */ - "adcs %[carry], %[carry] \n\t" /* Store carry bit. */ - "stmia %[dptr]!, {%[left]} \n\t" /* Store result word. */ - "subs %[ctr], #1 \n\t" /* Decrement counter. */ - "bne 1b \n\t" /* Loop until counter == 0. */ - #if (uECC_PLATFORM != uECC_arm_thumb2) - ".syntax divided \n\t" - #endif - #if (uECC_PLATFORM == uECC_arm_thumb) - : [dptr] "+l" (result), [lptr] "+l" (left), [rptr] "+l" (right), - [ctr] "+l" (counter), [carry] "+l" (carry), - [left] "=l" (left_word), [right] "=l" (right_word) - #else - : [dptr] "+r" (result), [lptr] "+r" (left), [rptr] "+r" (right), - [ctr] "+r" (counter), [carry] "+r" (carry), - [left] "=r" (left_word), [right] "=r" (right_word) - #endif - : - : "cc", "memory" - ); - return carry; -} -#define asm_add 1 -#endif - -#if !asm_sub -static uint32_t vli_sub(uint32_t *result, const uint32_t *left, const uint32_t *right) { - uint32_t counter = uECC_WORDS; - uint32_t carry = 1; /* carry = 1 initially (means don't borrow) */ - uint32_t left_word; - uint32_t right_word; - - __asm__ volatile ( - ".syntax unified \n\t" - "1: \n\t" - "ldmia %[lptr]!, {%[left]} \n\t" /* Load left word. */ - "ldmia %[rptr]!, {%[right]} \n\t" /* Load right word. */ - "lsrs %[carry], #1 \n\t" /* Set up carry flag (carry = 0 after this). */ - "sbcs %[left], %[right] \n\t" /* Subtract with borrow. */ - "adcs %[carry], %[carry] \n\t" /* Store carry bit. */ - "stmia %[dptr]!, {%[left]} \n\t" /* Store result word. */ - "subs %[ctr], #1 \n\t" /* Decrement counter. */ - "bne 1b \n\t" /* Loop until counter == 0. */ - #if (uECC_PLATFORM != uECC_arm_thumb2) - ".syntax divided \n\t" - #endif - #if (uECC_PLATFORM == uECC_arm_thumb) - : [dptr] "+l" (result), [lptr] "+l" (left), [rptr] "+l" (right), - [ctr] "+l" (counter), [carry] "+l" (carry), - [left] "=l" (left_word), [right] "=l" (right_word) - #else - : [dptr] "+r" (result), [lptr] "+r" (left), [rptr] "+r" (right), - [ctr] "+r" (counter), [carry] "+r" (carry), - [left] "=r" (left_word), [right] "=r" (right_word) - #endif - : - : "cc", "memory" - ); - return !carry; -} -#define asm_sub 1 -#endif - -#if !asm_mult -static void vli_mult(uint32_t *result, const uint32_t *left, const uint32_t *right) { -#if (uECC_PLATFORM != uECC_arm_thumb) - uint32_t c0 = 0; - uint32_t c1 = 0; - uint32_t c2 = 0; - uint32_t k = 0; - uint32_t i; - uint32_t t0, t1; - - __asm__ volatile ( - ".syntax unified \n\t" - - "1: \n\t" /* outer loop (k < uECC_WORDS) */ - "movs %[i], #0 \n\t" /* i = 0 */ - "b 3f \n\t" - - "2: \n\t" /* outer loop (k >= uECC_WORDS) */ - "movs %[i], %[k] \n\t" /* i = k */ - "subs %[i], %[eccdm1] \n\t" /* i = k - (uECC_WORDS - 1) (times 4) */ - - "3: \n\t" /* inner loop */ - "subs %[t0], %[k], %[i] \n\t" /* t0 = k-i */ - - "ldr %[t1], [%[right], %[t0]] \n\t" /* t1 = right[k - i] */ - "ldr %[t0], [%[left], %[i]] \n\t" /* t0 = left[i] */ - - "umull %[t0], %[t1], %[t0], %[t1] \n\t" /* (t0, t1) = left[i] * right[k - i] */ - - "adds %[c0], %[t0] \n\t" /* add low word to c0 */ - "adcs %[c1], %[t1] \n\t" /* add high word to c1, including carry */ - "adcs %[c2], #0 \n\t" /* add carry to c2 */ - - "adds %[i], #4 \n\t" /* i += 4 */ - "cmp %[i], %[eccd] \n\t" /* i < uECC_WORDS (times 4)? */ - "bge 4f \n\t" /* if not, exit the loop */ - "cmp %[i], %[k] \n\t" /* i <= k? */ - "ble 3b \n\t" /* if so, continue looping */ - - "4: \n\t" /* end inner loop */ - - "str %[c0], [%[result], %[k]] \n\t" /* result[k] = c0 */ - "mov %[c0], %[c1] \n\t" /* c0 = c1 */ - "mov %[c1], %[c2] \n\t" /* c1 = c2 */ - "movs %[c2], #0 \n\t" /* c2 = 0 */ - "adds %[k], #4 \n\t" /* k += 4 */ - "cmp %[k], %[eccd] \n\t" /* k < uECC_WORDS (times 4) ? */ - "blt 1b \n\t" /* if not, loop back, start with i = 0 */ - "cmp %[k], %[eccd2m1] \n\t" /* k < uECC_WORDS * 2 - 1 (times 4) ? */ - "blt 2b \n\t" /* if not, loop back, start with i = (k + 1) - uECC_WORDS */ - /* end outer loop */ - - "str %[c0], [%[result], %[k]] \n\t" /* result[uECC_WORDS * 2 - 1] = c0 */ - #if (uECC_PLATFORM != uECC_arm_thumb2) - ".syntax divided \n\t" - #endif - : [c0] "+r" (c0), [c1] "+r" (c1), [c2] "+r" (c2), - [k] "+r" (k), [i] "=&r" (i), [t0] "=&r" (t0), [t1] "=&r" (t1) - : [result] "r" (result), [left] "r" (left), [right] "r" (right), - [eccd] "I" (uECC_WORDS * 4), [eccdm1] "I" ((uECC_WORDS-1) * 4), - [eccd2m1] "I" ((uECC_WORDS * 2 - 1) * 4) - : "cc", "memory" - ); - -#else /* Thumb-1 */ - - register uint32_t *r0 __asm__("r0") = result; - register const uint32_t *r1 __asm__("r1") = left; - register const uint32_t *r2 __asm__("r2") = right; - - __asm__ volatile ( - ".syntax unified \n\t" - "movs r3, #0 \n\t" /* c0 = 0 */ - "movs r4, #0 \n\t" /* c1 = 0 */ - "movs r5, #0 \n\t" /* c2 = 0 */ - "movs r6, #0 \n\t" /* k = 0 */ - - "push {r0} \n\t" /* keep result on the stack */ - - "1: \n\t" /* outer loop (k < uECC_WORDS) */ - "movs r7, #0 \n\t" /* r7 = i = 0 */ - "b 3f \n\t" - - "2: \n\t" /* outer loop (k >= uECC_WORDS) */ - "movs r7, r6 \n\t" /* r7 = k */ - "subs r7, %[eccdm1] \n\t" /* r7 = i = k - (uECC_WORDS - 1) (times 4) */ - - "3: \n\t" /* inner loop */ - "push {r3, r4, r5, r6} \n\t" /* push things, r3 (c0) is at the top of stack. */ - "subs r0, r6, r7 \n\t" /* r0 = k - i */ - - "ldr r4, [r2, r0] \n\t" /* r4 = right[k - i] */ - "ldr r0, [r1, r7] \n\t" /* r0 = left[i] */ - - "lsrs r3, r0, #16 \n\t" /* r3 = a1 */ - "uxth r0, r0 \n\t" /* r0 = a0 */ - - "lsrs r5, r4, #16 \n\t" /* r5 = b1 */ - "uxth r4, r4 \n\t" /* r4 = b0 */ - - "movs r6, r3 \n\t" /* r6 = a1 */ - "muls r6, r5, r6 \n\t" /* r6 = a1 * b1 */ - "muls r3, r4, r3 \n\t" /* r3 = b0 * a1 */ - "muls r5, r0, r5 \n\t" /* r5 = a0 * b1 */ - "muls r0, r4, r0 \n\t" /* r0 = a0 * b0 */ - - "movs r4, #0 \n\t" /* r4 = 0 */ - "adds r3, r5 \n\t" /* r3 = b0 * a1 + a0 * b1 */ - "adcs r4, r4 \n\t" /* r4 = carry */ - "lsls r4, #16 \n\t" /* r4 = carry << 16 */ - "adds r6, r4 \n\t" /* r6 = a1 * b1 + carry */ - - "lsls r4, r3, #16 \n\t" /* r4 = (b0 * a1 + a0 * b1) << 16 */ - "lsrs r3, #16 \n\t" /* r3 = (b0 * a1 + a0 * b1) >> 16 */ - "adds r0, r4 \n\t" /* r0 = low word = a0 * b0 + ((b0 * a1 + a0 * b1) << 16) */ - "adcs r6, r3 \n\t" /* r6 = high word = a1 * b1 + carry + ((b0 * a1 + a0 * b1) >> 16) */ - - "pop {r3, r4, r5} \n\t" /* r3 = c0, r4 = c1, r5 = c2 */ - "adds r3, r0 \n\t" /* add low word to c0 */ - "adcs r4, r6 \n\t" /* add high word to c1, including carry */ - "movs r0, #0 \n\t" /* r0 = 0 (does not affect carry bit) */ - "adcs r5, r0 \n\t" /* add carry to c2 */ - - "pop {r6} \n\t" /* r6 = k */ - - "adds r7, #4 \n\t" /* i += 4 */ - "cmp r7, %[eccd] \n\t" /* i < uECC_WORDS (times 4)? */ - "bge 4f \n\t" /* if not, exit the loop */ - "cmp r7, r6 \n\t" /* i <= k? */ - "ble 3b \n\t" /* if so, continue looping */ - - "4: \n\t" /* end inner loop */ - - "ldr r0, [sp, #0] \n\t" /* r0 = result */ - - "str r3, [r0, r6] \n\t" /* result[k] = c0 */ - "mov r3, r4 \n\t" /* c0 = c1 */ - "mov r4, r5 \n\t" /* c1 = c2 */ - "movs r5, #0 \n\t" /* c2 = 0 */ - "adds r6, #4 \n\t" /* k += 4 */ - "cmp r6, %[eccd] \n\t" /* k < uECC_WORDS (times 4) ? */ - "blt 1b \n\t" /* if not, loop back, start with i = 0 */ - "cmp r6, %[eccd2m1] \n\t" /* k < uECC_WORDS * 2 - 1 (times 4) ? */ - "blt 2b \n\t" /* if not, loop back, start with i = (k + 1) - uECC_WORDS */ - /* end outer loop */ - - "str r3, [r0, r6] \n\t" /* result[uECC_WORDS * 2 - 1] = c0 */ - "pop {r0} \n\t" /* pop result off the stack */ - - ".syntax divided \n\t" - : - : [r0] "l" (r0), [r1] "l" (r1), [r2] "l" (r2), [eccd] "I" (uECC_WORDS * 4), [eccdm1] "I" ((uECC_WORDS-1) * 4), [eccd2m1] "I" ((uECC_WORDS * 2 - 1) * 4) - : "r3", "r4", "r5", "r6", "r7", "cc", "memory" - ); -#endif -} -#define asm_mult 1 -#endif /* !asm_mult */ - -#if uECC_SQUARE_FUNC -#if !asm_square -static void vli_square(uint32_t *result, const uint32_t *left) { -#if (uECC_PLATFORM != uECC_arm_thumb) - uint32_t c0 = 0; - uint32_t c1 = 0; - uint32_t c2 = 0; - uint32_t k = 0; - uint32_t i, tt; - uint32_t t0, t1; - - __asm__ volatile ( - ".syntax unified \n\t" - - "1: \n\t" /* outer loop (k < uECC_WORDS) */ - "movs %[i], #0 \n\t" /* i = 0 */ - "b 3f \n\t" - - "2: \n\t" /* outer loop (k >= uECC_WORDS) */ - "movs %[i], %[k] \n\t" /* i = k */ - "subs %[i], %[eccdm1] \n\t" /* i = k - (uECC_WORDS - 1) (times 4) */ - - "3: \n\t" /* inner loop */ - "subs %[tt], %[k], %[i] \n\t" /* tt = k-i */ - - "ldr %[t1], [%[left], %[tt]] \n\t" /* t1 = left[k - i] */ - "ldr %[t0], [%[left], %[i]] \n\t" /* t0 = left[i] */ - - "umull %[t0], %[t1], %[t0], %[t1] \n\t" /* (t0, t1) = left[i] * right[k - i] */ - - "cmp %[i], %[tt] \n\t" /* (i < k - i) ? */ - "bge 4f \n\t" /* if i >= k - i, skip */ - "lsls %[t1], #1 \n\t" /* high word << 1 */ - "adc %[c2], #0 \n\t" /* add carry bit to c2 */ - "lsls %[t0], #1 \n\t" /* low word << 1 */ - "adc %[t1], #0 \n\t" /* add carry bit to high word */ - - "4: \n\t" - - "adds %[c0], %[t0] \n\t" /* add low word to c0 */ - "adcs %[c1], %[t1] \n\t" /* add high word to c1, including carry */ - "adc %[c2], #0 \n\t" /* add carry to c2 */ - - "adds %[i], #4 \n\t" /* i += 4 */ - "cmp %[i], %[k] \n\t" /* i <= k? */ - "bge 5f \n\t" /* if not, exit the loop */ - "subs %[tt], %[k], %[i] \n\t" /* tt = k - i */ - "cmp %[i], %[tt] \n\t" /* i <= k - i? */ - "ble 3b \n\t" /* if so, continue looping */ - - "5: \n\t" /* end inner loop */ - - "str %[c0], [%[result], %[k]] \n\t" /* result[k] = c0 */ - "mov %[c0], %[c1] \n\t" /* c0 = c1 */ - "mov %[c1], %[c2] \n\t" /* c1 = c2 */ - "movs %[c2], #0 \n\t" /* c2 = 0 */ - "adds %[k], #4 \n\t" /* k += 4 */ - "cmp %[k], %[eccd] \n\t" /* k < uECC_WORDS (times 4) ? */ - "blt 1b \n\t" /* if not, loop back, start with i = 0 */ - "cmp %[k], %[eccd2m1] \n\t" /* k < uECC_WORDS * 2 - 1 (times 4) ? */ - "blt 2b \n\t" /* if not, loop back, start with i = (k + 1) - uECC_WORDS */ - /* end outer loop */ - - "str %[c0], [%[result], %[k]] \n\t" /* result[uECC_WORDS * 2 - 1] = c0 */ - #if (uECC_PLATFORM != uECC_arm_thumb2) - ".syntax divided \n\t" - #endif - : [c0] "+r" (c0), [c1] "+r" (c1), [c2] "+r" (c2), - [k] "+r" (k), [i] "=&r" (i), [tt] "=&r" (tt), [t0] "=&r" (t0), [t1] "=&r" (t1) - : [result] "r" (result), [left] "r" (left), - [eccd] "I" (uECC_WORDS * 4), [eccdm1] "I" ((uECC_WORDS-1) * 4), - [eccd2m1] "I" ((uECC_WORDS * 2 - 1) * 4) - : "cc", "memory" - ); - -#else - - register uint32_t *r0 __asm__("r0") = result; - register const uint32_t *r1 __asm__("r1") = left; - - __asm__ volatile ( - ".syntax unified \n\t" - "movs r2, #0 \n\t" /* c0 = 0 */ - "movs r3, #0 \n\t" /* c1 = 0 */ - "movs r4, #0 \n\t" /* c2 = 0 */ - "movs r5, #0 \n\t" /* k = 0 */ - - "push {r0} \n\t" /* keep result on the stack */ - - "1: \n\t" /* outer loop (k < uECC_WORDS) */ - "movs r6, #0 \n\t" /* r6 = i = 0 */ - "b 3f \n\t" - - "2: \n\t" /* outer loop (k >= uECC_WORDS) */ - "movs r6, r5 \n\t" /* r6 = k */ - "subs r6, %[eccdm1] \n\t" /* r6 = i = k - (uECC_WORDS - 1) (times 4) */ - - "3: \n\t" /* inner loop */ - "push {r2, r3, r4, r5} \n\t" /* push things, r2 (c0) is at the top of stack. */ - "subs r7, r5, r6 \n\t" /* r7 = k - i */ - - "ldr r3, [r1, r7] \n\t" /* r3 = left[k - i] */ - "ldr r0, [r1, r6] \n\t" /* r0 = left[i] */ - - "lsrs r2, r0, #16 \n\t" /* r2 = a1 */ - "uxth r0, r0 \n\t" /* r0 = a0 */ - - "lsrs r4, r3, #16 \n\t" /* r4 = b1 */ - "uxth r3, r3 \n\t" /* r3 = b0 */ - - "movs r5, r2 \n\t" /* r5 = a1 */ - "muls r5, r4, r5 \n\t" /* r5 = a1 * b1 */ - "muls r2, r3, r2 \n\t" /* r2 = b0 * a1 */ - "muls r4, r0, r4 \n\t" /* r4 = a0 * b1 */ - "muls r0, r3, r0 \n\t" /* r0 = a0 * b0 */ - - "movs r3, #0 \n\t" /* r3 = 0 */ - "adds r2, r4 \n\t" /* r2 = b0 * a1 + a0 * b1 */ - "adcs r3, r3 \n\t" /* r3 = carry */ - "lsls r3, #16 \n\t" /* r3 = carry << 16 */ - "adds r5, r3 \n\t" /* r5 = a1 * b1 + carry */ - - "lsls r3, r2, #16 \n\t" /* r3 = (b0 * a1 + a0 * b1) << 16 */ - "lsrs r2, #16 \n\t" /* r2 = (b0 * a1 + a0 * b1) >> 16 */ - "adds r0, r3 \n\t" /* r0 = low word = a0 * b0 + ((b0 * a1 + a0 * b1) << 16) */ - "adcs r5, r2 \n\t" /* r5 = high word = a1 * b1 + carry + ((b0 * a1 + a0 * b1) >> 16) */ - - "movs r3, #0 \n\t" /* r3 = 0 */ - "cmp r6, r7 \n\t" /* (i < k - i) ? */ - "mov r7, r3 \n\t" /* r7 = 0 (does not affect condition)*/ - "bge 4f \n\t" /* if i >= k - i, skip */ - "lsls r5, #1 \n\t" /* high word << 1 */ - "adcs r7, r3 \n\t" /* r7 = carry bit for c2 */ - "lsls r0, #1 \n\t" /* low word << 1 */ - "adcs r5, r3 \n\t" /* add carry from shift to high word */ - - "4: \n\t" - "pop {r2, r3, r4} \n\t" /* r2 = c0, r3 = c1, r4 = c2 */ - "adds r2, r0 \n\t" /* add low word to c0 */ - "adcs r3, r5 \n\t" /* add high word to c1, including carry */ - "movs r0, #0 \n\t" /* r0 = 0 (does not affect carry bit) */ - "adcs r4, r0 \n\t" /* add carry to c2 */ - "adds r4, r7 \n\t" /* add carry from doubling (if any) */ - - "pop {r5} \n\t" /* r5 = k */ - - "adds r6, #4 \n\t" /* i += 4 */ - "cmp r6, r5 \n\t" /* i <= k? */ - "bge 5f \n\t" /* if not, exit the loop */ - "subs r7, r5, r6 \n\t" /* r7 = k - i */ - "cmp r6, r7 \n\t" /* i <= k - i? */ - "ble 3b \n\t" /* if so, continue looping */ - - "5: \n\t" /* end inner loop */ - - "ldr r0, [sp, #0] \n\t" /* r0 = result */ - - "str r2, [r0, r5] \n\t" /* result[k] = c0 */ - "mov r2, r3 \n\t" /* c0 = c1 */ - "mov r3, r4 \n\t" /* c1 = c2 */ - "movs r4, #0 \n\t" /* c2 = 0 */ - "adds r5, #4 \n\t" /* k += 4 */ - "cmp r5, %[eccd] \n\t" /* k < uECC_WORDS (times 4) ? */ - "blt 1b \n\t" /* if not, loop back, start with i = 0 */ - "cmp r5, %[eccd2m1] \n\t" /* k < uECC_WORDS * 2 - 1 (times 4) ? */ - "blt 2b \n\t" /* if not, loop back, start with i = (k + 1) - uECC_WORDS */ - /* end outer loop */ - - "str r2, [r0, r5] \n\t" /* result[uECC_WORDS * 2 - 1] = c0 */ - "pop {r0} \n\t" /* pop result off the stack */ - - ".syntax divided \n\t" - : [r0] "+l" (r0), [r1] "+l" (r1) - : [eccd] "I" (uECC_WORDS * 4), [eccdm1] "I" ((uECC_WORDS-1) * 4), - [eccd2m1] "I" ((uECC_WORDS * 2 - 1) * 4) - : "r2", "r3", "r4", "r5", "r6", "r7", "cc", "memory" - ); -#endif -} -#define asm_square 1 -#endif /* !asm_square */ -#endif /* uECC_SQUARE_FUNC */ diff --git a/asm_arm_fast.inc b/asm_arm_fast.inc new file mode 100644 index 0000000..150afa0 --- /dev/null +++ b/asm_arm_fast.inc @@ -0,0 +1,845 @@ +/* Copyright 2015, Kenneth MacKay. Licensed under the BSD 2-clause license. */ + +#ifndef _UECC_ASM_ARM_FAST_H_ +#define _UECC_ASM_ARM_FAST_H_ + +#if (uECC_SUPPORTS_secp256r1 || uECC_SUPPORTS_secp256k1) + #define uECC_MIN_WORDS 8 +#endif +#if uECC_SUPPORTS_secp224r1 + #undef uECC_MIN_WORDS + #define uECC_MIN_WORDS 7 +#endif +#if uECC_SUPPORTS_secp192r1 + #undef uECC_MIN_WORDS + #define uECC_MIN_WORDS 6 +#endif +#if uECC_SUPPORTS_secp160r1 + #undef uECC_MIN_WORDS + #define uECC_MIN_WORDS 5 +#endif + +#if (uECC_PLATFORM == uECC_arm_thumb) + #define REG_RW "+l" + #define REG_WRITE "=l" +#else + #define REG_RW "+r" + #define REG_WRITE "=r" +#endif + +#if (uECC_PLATFORM == uECC_arm_thumb2) + #define RESUME_SYNTAX +#else + #define RESUME_SYNTAX ".syntax divided \n\t" +#endif + +static uECC_word_t 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 */ + uint32_t jump = ((uECC_MAX_WORDS - num_words) * 4 + 5) * 4; +#endif + uint32_t carry; + uint32_t left_word; + uint32_t right_word; + + __asm__ volatile ( + ".syntax unified \n\t" + "movs %[carry], #0 \n\t" + "mov %[left], pc \n\t" + "adds %[jump], %[left] \n\t" + + "ldmia %[lptr]!, {%[left]} \n\t" + "ldmia %[rptr]!, {%[right]} \n\t" + "adds %[left], %[right] \n\t" + "stmia %[dptr]!, {%[left]} \n\t" + + "bx %[jump] \n\t" + + "ldmia %[lptr]!, {%[left]} \n\t" + "ldmia %[rptr]!, {%[right]} \n\t" + "adcs %[left], %[right] \n\t" + "stmia %[dptr]!, {%[left]} \n\t" + + "ldmia %[lptr]!, {%[left]} \n\t" + "ldmia %[rptr]!, {%[right]} \n\t" + "adcs %[left], %[right] \n\t" + "stmia %[dptr]!, {%[left]} \n\t" + + "ldmia %[lptr]!, {%[left]} \n\t" + "ldmia %[rptr]!, {%[right]} \n\t" + "adcs %[left], %[right] \n\t" + "stmia %[dptr]!, {%[left]} \n\t" + + "ldmia %[lptr]!, {%[left]} \n\t" + "ldmia %[rptr]!, {%[right]} \n\t" + "adcs %[left], %[right] \n\t" + "stmia %[dptr]!, {%[left]} \n\t" + + #if (uECC_MAX_WORDS >= 6) + "ldmia %[lptr]!, {%[left]} \n\t" + "ldmia %[rptr]!, {%[right]} \n\t" + "adcs %[left], %[right] \n\t" + "stmia %[dptr]!, {%[left]} \n\t" + #endif + #if (uECC_MAX_WORDS >= 7) + "ldmia %[lptr]!, {%[left]} \n\t" + "ldmia %[rptr]!, {%[right]} \n\t" + "adcs %[left], %[right] \n\t" + "stmia %[dptr]!, {%[left]} \n\t" + #endif + #if (uECC_MAX_WORDS >= 8) + "ldmia %[lptr]!, {%[left]} \n\t" + "ldmia %[rptr]!, {%[right]} \n\t" + "adcs %[left], %[right] \n\t" + "stmia %[dptr]!, {%[left]} \n\t" + #endif + "adcs %[carry], %[carry] \n\t" + RESUME_SYNTAX + : [dptr] REG_RW (result), [lptr] REG_RW (left), [rptr] REG_RW (right), + [carry] REG_WRITE (carry), [left] REG_WRITE (left_word), [right] REG_WRITE (right_word), + [jump] REG_RW (jump) + : + : "cc", "memory" + ); + return carry; +} +#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) { +#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 */ + uint32_t jump = ((uECC_MAX_WORDS - num_words) * 4 + 5) * 4; +#endif + uint32_t carry; + uint32_t left_word; + uint32_t right_word; + + __asm__ volatile ( + ".syntax unified \n\t" + "movs %[carry], #0 \n\t" + "mov %[left], pc \n\t" + "adds %[jump], %[left] \n\t" + + "ldmia %[lptr]!, {%[left]} \n\t" + "ldmia %[rptr]!, {%[right]} \n\t" + "subs %[left], %[right] \n\t" + "stmia %[dptr]!, {%[left]} \n\t" + + "bx %[jump] \n\t" + + "ldmia %[lptr]!, {%[left]} \n\t" + "ldmia %[rptr]!, {%[right]} \n\t" + "sbcs %[left], %[right] \n\t" + "stmia %[dptr]!, {%[left]} \n\t" + + "ldmia %[lptr]!, {%[left]} \n\t" + "ldmia %[rptr]!, {%[right]} \n\t" + "sbcs %[left], %[right] \n\t" + "stmia %[dptr]!, {%[left]} \n\t" + + "ldmia %[lptr]!, {%[left]} \n\t" + "ldmia %[rptr]!, {%[right]} \n\t" + "sbcs %[left], %[right] \n\t" + "stmia %[dptr]!, {%[left]} \n\t" + + "ldmia %[lptr]!, {%[left]} \n\t" + "ldmia %[rptr]!, {%[right]} \n\t" + "sbcs %[left], %[right] \n\t" + "stmia %[dptr]!, {%[left]} \n\t" + + #if (uECC_MAX_WORDS >= 6) + "ldmia %[lptr]!, {%[left]} \n\t" + "ldmia %[rptr]!, {%[right]} \n\t" + "sbcs %[left], %[right] \n\t" + "stmia %[dptr]!, {%[left]} \n\t" + #endif + #if (uECC_MAX_WORDS >= 7) + "ldmia %[lptr]!, {%[left]} \n\t" + "ldmia %[rptr]!, {%[right]} \n\t" + "sbcs %[left], %[right] \n\t" + "stmia %[dptr]!, {%[left]} \n\t" + #endif + #if (uECC_MAX_WORDS >= 8) + "ldmia %[lptr]!, {%[left]} \n\t" + "ldmia %[rptr]!, {%[right]} \n\t" + "sbcs %[left], %[right] \n\t" + "stmia %[dptr]!, {%[left]} \n\t" + #endif + "adcs %[carry], %[carry] \n\t" + RESUME_SYNTAX + : [dptr] REG_RW (result), [lptr] REG_RW (left), [rptr] REG_RW (right), + [carry] REG_WRITE (carry), [left] REG_WRITE (left_word), [right] REG_WRITE (right_word), + [jump] REG_RW (jump) + : + : "cc", "memory" + ); + return !carry; /* Note that on ARM, carry flag set means "no borrow" when subtracting + (for some reason...) */ +} +#define asm_sub 1 + +#define FAST_MULT_ASM_5_TO_6 \ + "cmp r3, #5 \n\t" \ + "beq 1f \n\t" \ + \ + /* r4 = left high, r5 = right high */ \ + "ldr r4, [r1] \n\t" \ + "ldr r5, [r2] \n\t" \ + \ + "sub r0, #20 \n\t" \ + "sub r1, #20 \n\t" \ + "sub r2, #20 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "ldr r7, [r1], #4 \n\t" \ + "ldr r8, [r2], #4 \n\t" \ + "mov r14, #0 \n\t" \ + "umull r9, r10, r4, r8 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r9, r6 \n\t" \ + "adc r10, #0 \n\t" \ + "adds r9, r11 \n\t" \ + "adcs r10, r12 \n\t" \ + "adc r14, #0 \n\t" \ + "str r9, [r0], #4 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "adds r10, r6 \n\t" \ + "adcs r14, #0 \n\t" \ + "ldr r7, [r1], #4 \n\t" \ + "ldr r8, [r2], #4 \n\t" \ + "mov r9, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r10, r11 \n\t" \ + "adcs r14, r12 \n\t" \ + "adc r9, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r10, r11 \n\t" \ + "adcs r14, r12 \n\t" \ + "adc r9, #0 \n\t" \ + "str r10, [r0], #4 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "adds r14, r6 \n\t" \ + "adcs r9, #0 \n\t" \ + "ldr r7, [r1], #4 \n\t" \ + "ldr r8, [r2], #4 \n\t" \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r14, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r14, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "str r14, [r0], #4 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "adds r9, r6 \n\t" \ + "adcs r10, #0 \n\t" \ + "ldr r7, [r1], #4 \n\t" \ + "ldr r8, [r2], #4 \n\t" \ + "mov r14, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r9, r11 \n\t" \ + "adcs r10, r12 \n\t" \ + "adc r14, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r9, r11 \n\t" \ + "adcs r10, r12 \n\t" \ + "adc r14, #0 \n\t" \ + "str r9, [r0], #4 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "adds r10, r6 \n\t" \ + "adcs r14, #0 \n\t" \ + /* skip past already-loaded (r4, r5) */ \ + "ldr r7, [r1], #8 \n\t" \ + "ldr r8, [r2], #8 \n\t" \ + "mov r9, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r10, r11 \n\t" \ + "adcs r14, r12 \n\t" \ + "adc r9, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r10, r11 \n\t" \ + "adcs r14, r12 \n\t" \ + "adc r9, #0 \n\t" \ + "str r10, [r0], #4 \n\t" \ + \ + "umull r11, r12, r4, r5 \n\t" \ + "adds r11, r14 \n\t" \ + "adc r12, r9 \n\t" \ + "stmia r0!, {r11, r12} \n\t" + +#define FAST_MULT_ASM_6_TO_7 \ + "cmp r3, #6 \n\t" \ + "beq 1f \n\t" \ + \ + /* r4 = left high, r5 = right high */ \ + "ldr r4, [r1] \n\t" \ + "ldr r5, [r2] \n\t" \ + \ + "sub r0, #24 \n\t" \ + "sub r1, #24 \n\t" \ + "sub r2, #24 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "ldr r7, [r1], #4 \n\t" \ + "ldr r8, [r2], #4 \n\t" \ + "mov r14, #0 \n\t" \ + "umull r9, r10, r4, r8 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r9, r6 \n\t" \ + "adc r10, #0 \n\t" \ + "adds r9, r11 \n\t" \ + "adcs r10, r12 \n\t" \ + "adc r14, #0 \n\t" \ + "str r9, [r0], #4 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "adds r10, r6 \n\t" \ + "adcs r14, #0 \n\t" \ + "ldr r7, [r1], #4 \n\t" \ + "ldr r8, [r2], #4 \n\t" \ + "mov r9, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r10, r11 \n\t" \ + "adcs r14, r12 \n\t" \ + "adc r9, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r10, r11 \n\t" \ + "adcs r14, r12 \n\t" \ + "adc r9, #0 \n\t" \ + "str r10, [r0], #4 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "adds r14, r6 \n\t" \ + "adcs r9, #0 \n\t" \ + "ldr r7, [r1], #4 \n\t" \ + "ldr r8, [r2], #4 \n\t" \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r14, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r14, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "str r14, [r0], #4 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "adds r9, r6 \n\t" \ + "adcs r10, #0 \n\t" \ + "ldr r7, [r1], #4 \n\t" \ + "ldr r8, [r2], #4 \n\t" \ + "mov r14, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r9, r11 \n\t" \ + "adcs r10, r12 \n\t" \ + "adc r14, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r9, r11 \n\t" \ + "adcs r10, r12 \n\t" \ + "adc r14, #0 \n\t" \ + "str r9, [r0], #4 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "adds r10, r6 \n\t" \ + "adcs r14, #0 \n\t" \ + "ldr r7, [r1], #4 \n\t" \ + "ldr r8, [r2], #4 \n\t" \ + "mov r9, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r10, r11 \n\t" \ + "adcs r14, r12 \n\t" \ + "adc r9, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r10, r11 \n\t" \ + "adcs r14, r12 \n\t" \ + "adc r9, #0 \n\t" \ + "str r10, [r0], #4 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "adds r14, r6 \n\t" \ + "adcs r9, #0 \n\t" \ + /* skip past already-loaded (r4, r5) */ \ + "ldr r7, [r1], #8 \n\t" \ + "ldr r8, [r2], #8 \n\t" \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r14, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r14, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "str r14, [r0], #4 \n\t" \ + \ + "umull r11, r12, r4, r5 \n\t" \ + "adds r11, r9 \n\t" \ + "adc r12, r10 \n\t" \ + "stmia r0!, {r11, r12} \n\t" + +#define FAST_MULT_ASM_7_TO_8 \ + "cmp r3, #7 \n\t" \ + "beq 1f \n\t" \ + \ + /* r4 = left high, r5 = right high */ \ + "ldr r4, [r1] \n\t" \ + "ldr r5, [r2] \n\t" \ + \ + "sub r0, #28 \n\t" \ + "sub r1, #28 \n\t" \ + "sub r2, #28 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "ldr r7, [r1], #4 \n\t" \ + "ldr r8, [r2], #4 \n\t" \ + "mov r14, #0 \n\t" \ + "umull r9, r10, r4, r8 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r9, r6 \n\t" \ + "adc r10, #0 \n\t" \ + "adds r9, r11 \n\t" \ + "adcs r10, r12 \n\t" \ + "adc r14, #0 \n\t" \ + "str r9, [r0], #4 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "adds r10, r6 \n\t" \ + "adcs r14, #0 \n\t" \ + "ldr r7, [r1], #4 \n\t" \ + "ldr r8, [r2], #4 \n\t" \ + "mov r9, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r10, r11 \n\t" \ + "adcs r14, r12 \n\t" \ + "adc r9, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r10, r11 \n\t" \ + "adcs r14, r12 \n\t" \ + "adc r9, #0 \n\t" \ + "str r10, [r0], #4 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "adds r14, r6 \n\t" \ + "adcs r9, #0 \n\t" \ + "ldr r7, [r1], #4 \n\t" \ + "ldr r8, [r2], #4 \n\t" \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r14, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r14, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "str r14, [r0], #4 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "adds r9, r6 \n\t" \ + "adcs r10, #0 \n\t" \ + "ldr r7, [r1], #4 \n\t" \ + "ldr r8, [r2], #4 \n\t" \ + "mov r14, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r9, r11 \n\t" \ + "adcs r10, r12 \n\t" \ + "adc r14, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r9, r11 \n\t" \ + "adcs r10, r12 \n\t" \ + "adc r14, #0 \n\t" \ + "str r9, [r0], #4 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "adds r10, r6 \n\t" \ + "adcs r14, #0 \n\t" \ + "ldr r7, [r1], #4 \n\t" \ + "ldr r8, [r2], #4 \n\t" \ + "mov r9, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r10, r11 \n\t" \ + "adcs r14, r12 \n\t" \ + "adc r9, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r10, r11 \n\t" \ + "adcs r14, r12 \n\t" \ + "adc r9, #0 \n\t" \ + "str r10, [r0], #4 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "adds r14, r6 \n\t" \ + "adcs r9, #0 \n\t" \ + "ldr r7, [r1], #4 \n\t" \ + "ldr r8, [r2], #4 \n\t" \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r14, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r14, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "str r14, [r0], #4 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "adds r9, r6 \n\t" \ + "adcs r10, #0 \n\t" \ + /* skip past already-loaded (r4, r5) */ \ + "ldr r7, [r1], #8 \n\t" \ + "ldr r8, [r2], #8 \n\t" \ + "mov r14, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r9, r11 \n\t" \ + "adcs r10, r12 \n\t" \ + "adc r14, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r9, r11 \n\t" \ + "adcs r10, r12 \n\t" \ + "adc r14, #0 \n\t" \ + "str r9, [r0], #4 \n\t" \ + \ + "umull r11, r12, r4, r5 \n\t" \ + "adds r11, r10 \n\t" \ + "adc r12, r14 \n\t" \ + "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) { + register uint32_t *r0 __asm__("r0") = result; + register const uint32_t *r1 __asm__("r1") = left; + register const uint32_t *r2 __asm__("r2") = right; + register uint32_t r3 __asm__("r3") = num_words; + + __asm__ volatile ( + ".syntax unified \n\t" + "push {r3} \n\t" + +#if (uECC_MIN_WORDS == 5) + FAST_MULT_ASM_5 + "pop {r3} \n\t" + #if (uECC_MAX_WORDS > 5) + FAST_MULT_ASM_5_TO_6 + #endif + #if (uECC_MAX_WORDS > 6) + FAST_MULT_ASM_6_TO_7 + #endif + #if (uECC_MAX_WORDS > 7) + FAST_MULT_ASM_7_TO_8 + #endif +#elif (uECC_MIN_WORDS == 6) + FAST_MULT_ASM_6 + "pop {r3} \n\t" + #if (uECC_MAX_WORDS > 6) + FAST_MULT_ASM_6_TO_7 + #endif + #if (uECC_MAX_WORDS > 7) + FAST_MULT_ASM_7_TO_8 + #endif +#elif (uECC_MIN_WORDS == 7) + FAST_MULT_ASM_7 + "pop {r3} \n\t" + #if (uECC_MAX_WORDS > 7) + FAST_MULT_ASM_7_TO_8 + #endif +#elif (uECC_MIN_WORDS == 8) + FAST_MULT_ASM_8 + "pop {r3} \n\t" +#endif + + "1: \n\t" + RESUME_SYNTAX + : "+r" (r0), "+r" (r1), "+r" (r2) + : "r" (r3) + : "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory" + ); +} +#define asm_mult 1 + +#if uECC_SQUARE_FUNC + +#define FAST_SQUARE_ASM_5_TO_6 \ + "cmp r2, #5 \n\t" \ + "beq 1f \n\t" \ + \ + /* r3 = high */ \ + "ldr r3, [r1] \n\t" \ + \ + "sub r0, #20 \n\t" \ + "sub r1, #20 \n\t" \ + \ + /* Do off-center multiplication */ \ + "ldr r14, [r1], #4 \n\t" \ + "umull r4, r5, r3, r14 \n\t" \ + "ldr r14, [r1], #4 \n\t" \ + "umull r7, r6, r3, r14 \n\t" \ + "adds r5, r7 \n\t" \ + "ldr r14, [r1], #4 \n\t" \ + "umull r8, r7, r3, r14 \n\t" \ + "adcs r6, r8 \n\t" \ + "ldr r14, [r1], #4 \n\t" \ + "umull r9, r8, r3, r14 \n\t" \ + "adcs r7, r9 \n\t" \ + /* Skip already-loaded r3 */ \ + "ldr r14, [r1], #8 \n\t" \ + "umull r10, r9, r3, r14 \n\t" \ + "adcs r8, r10 \n\t" \ + "adcs r9, #0 \n\t" \ + \ + /* Multiply by 2 */ \ + "mov r10, #0 \n\t" \ + "adds r4, r4 \n\t" \ + "adcs r5, r5 \n\t" \ + "adcs r6, r6 \n\t" \ + "adcs r7, r7 \n\t" \ + "adcs r8, r8 \n\t" \ + "adcs r9, r9 \n\t" \ + "adcs r10, #0 \n\t" \ + \ + /* Add into previous */ \ + "ldr r14, [r0] \n\t" \ + "adds r4, r14 \n\t" \ + "str r4, [r0], #4 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adcs r5, r14 \n\t" \ + "str r5, [r0], #4 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adcs r6, r14 \n\t" \ + "str r6, [r0], #4 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adcs r7, r14 \n\t" \ + "str r7, [r0], #4 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adcs r8, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "adcs r9, #0 \n\t" \ + "adcs r10, #0 \n\t" \ + \ + /* Perform center multiplication */ \ + "umull r4, r5, r3, r3 \n\t" \ + "adds r4, r9 \n\t" \ + "adc r5, r10 \n\t" \ + "stmia r0!, {r4, r5} \n\t" + +#define FAST_SQUARE_ASM_6_TO_7 \ + "cmp r2, #6 \n\t" \ + "beq 1f \n\t" \ + \ + /* r3 = high */ \ + "ldr r3, [r1] \n\t" \ + \ + "sub r0, #24 \n\t" \ + "sub r1, #24 \n\t" \ + \ + /* Do off-center multiplication */ \ + "ldr r14, [r1], #4 \n\t" \ + "umull r4, r5, r3, r14 \n\t" \ + "ldr r14, [r1], #4 \n\t" \ + "umull r7, r6, r3, r14 \n\t" \ + "adds r5, r7 \n\t" \ + "ldr r14, [r1], #4 \n\t" \ + "umull r8, r7, r3, r14 \n\t" \ + "adcs r6, r8 \n\t" \ + "ldr r14, [r1], #4 \n\t" \ + "umull r9, r8, r3, r14 \n\t" \ + "adcs r7, r9 \n\t" \ + "ldr r14, [r1], #4 \n\t" \ + "umull r10, r9, r3, r14 \n\t" \ + "adcs r8, r10 \n\t" \ + /* Skip already-loaded r3 */ \ + "ldr r14, [r1], #8 \n\t" \ + "umull r11, r10, r3, r14 \n\t" \ + "adcs r9, r11 \n\t" \ + "adcs r10, #0 \n\t" \ + \ + /* Multiply by 2 */ \ + "mov r11, #0 \n\t" \ + "adds r4, r4 \n\t" \ + "adcs r5, r5 \n\t" \ + "adcs r6, r6 \n\t" \ + "adcs r7, r7 \n\t" \ + "adcs r8, r8 \n\t" \ + "adcs r9, r9 \n\t" \ + "adcs r10, r10 \n\t" \ + "adcs r11, #0 \n\t" \ + \ + /* Add into previous */ \ + "ldr r14, [r0] \n\t" \ + "adds r4, r14 \n\t" \ + "str r4, [r0], #4 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adcs r5, r14 \n\t" \ + "str r5, [r0], #4 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adcs r6, r14 \n\t" \ + "str r6, [r0], #4 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adcs r7, r14 \n\t" \ + "str r7, [r0], #4 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adcs r8, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adcs r9, r14 \n\t" \ + "str r9, [r0], #4 \n\t" \ + "adcs r10, #0 \n\t" \ + "adcs r11, #0 \n\t" \ + \ + /* Perform center multiplication */ \ + "umull r4, r5, r3, r3 \n\t" \ + "adds r4, r10 \n\t" \ + "adc r5, r11 \n\t" \ + "stmia r0!, {r4, r5} \n\t" + +#define FAST_SQUARE_ASM_7_TO_8 \ + "cmp r2, #7 \n\t" \ + "beq 1f \n\t" \ + \ + /* r3 = high */ \ + "ldr r3, [r1] \n\t" \ + \ + "sub r0, #28 \n\t" \ + "sub r1, #28 \n\t" \ + \ + /* Do off-center multiplication */ \ + "ldr r14, [r1], #4 \n\t" \ + "umull r4, r5, r3, r14 \n\t" \ + "ldr r14, [r1], #4 \n\t" \ + "umull r7, r6, r3, r14 \n\t" \ + "adds r5, r7 \n\t" \ + "ldr r14, [r1], #4 \n\t" \ + "umull r8, r7, r3, r14 \n\t" \ + "adcs r6, r8 \n\t" \ + "ldr r14, [r1], #4 \n\t" \ + "umull r9, r8, r3, r14 \n\t" \ + "adcs r7, r9 \n\t" \ + "ldr r14, [r1], #4 \n\t" \ + "umull r10, r9, r3, r14 \n\t" \ + "adcs r8, r10 \n\t" \ + "ldr r14, [r1], #4 \n\t" \ + "umull r11, r10, r3, r14 \n\t" \ + "adcs r9, r11 \n\t" \ + /* Skip already-loaded r3 */ \ + "ldr r14, [r1], #8 \n\t" \ + "umull r12, r11, r3, r14 \n\t" \ + "adcs r10, r12 \n\t" \ + "adcs r11, #0 \n\t" \ + \ + /* Multiply by 2 */ \ + "mov r12, #0 \n\t" \ + "adds r4, r4 \n\t" \ + "adcs r5, r5 \n\t" \ + "adcs r6, r6 \n\t" \ + "adcs r7, r7 \n\t" \ + "adcs r8, r8 \n\t" \ + "adcs r9, r9 \n\t" \ + "adcs r10, r10 \n\t" \ + "adcs r11, r11 \n\t" \ + "adcs r12, #0 \n\t" \ + \ + /* Add into previous */ \ + "ldr r14, [r0] \n\t" \ + "adds r4, r14 \n\t" \ + "str r4, [r0], #4 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adcs r5, r14 \n\t" \ + "str r5, [r0], #4 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adcs r6, r14 \n\t" \ + "str r6, [r0], #4 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adcs r7, r14 \n\t" \ + "str r7, [r0], #4 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adcs r8, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adcs r9, r14 \n\t" \ + "str r9, [r0], #4 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adcs r10, r14 \n\t" \ + "str r10, [r0], #4 \n\t" \ + "adcs r11, #0 \n\t" \ + "adcs r12, #0 \n\t" \ + \ + /* Perform center multiplication */ \ + "umull r4, r5, r3, r3 \n\t" \ + "adds r4, r11 \n\t" \ + "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) { + register uint32_t *r0 __asm__("r0") = result; + register const uint32_t *r1 __asm__("r1") = left; + register uint32_t r2 __asm__("r2") = num_words; + + __asm__ volatile ( + ".syntax unified \n\t" + "push {r1, r2} \n\t" + +#if (uECC_MIN_WORDS == 5) + FAST_SQUARE_ASM_5 + "pop {r1, r2} \n\t" + #if (uECC_MAX_WORDS > 5) + "add r1, #20 \n\t" + FAST_SQUARE_ASM_5_TO_6 + #endif + #if (uECC_MAX_WORDS > 6) + FAST_SQUARE_ASM_6_TO_7 + #endif + #if (uECC_MAX_WORDS > 7) + FAST_SQUARE_ASM_7_TO_8 + #endif +#elif (uECC_MIN_WORDS == 6) + FAST_SQUARE_ASM_6 + "pop {r1, r2} \n\t" + #if (uECC_MAX_WORDS > 6) + "add r1, #24 \n\t" + FAST_SQUARE_ASM_6_TO_7 + #endif + #if (uECC_MAX_WORDS > 7) + FAST_SQUARE_ASM_7_TO_8 + #endif +#elif (uECC_MIN_WORDS == 7) + FAST_SQUARE_ASM_7 + "pop {r1, r2} \n\t" + #if (uECC_MAX_WORDS > 7) + "add r1, #28 \n\t" + FAST_SQUARE_ASM_7_TO_8 + #endif +#elif (uECC_MIN_WORDS == 8) + FAST_SQUARE_ASM_8 + "pop {r1, r2} \n\t" +#endif + + "1: \n\t" + RESUME_SYNTAX + : "+r" (r0), "+r" (r1) + : "r" (r2) + : "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory" + ); +} +#define asm_square 1 +#endif /* uECC_SQUARE_FUNC */ + +#endif /* uECC_PLATFORM != uECC_arm_thumb */ + +#endif /* _UECC_ASM_ARM_FAST_H_ */ diff --git a/asm_arm_mult_square.inc b/asm_arm_mult_square.inc new file mode 100644 index 0000000..d46af78 --- /dev/null +++ b/asm_arm_mult_square.inc @@ -0,0 +1,1808 @@ +/* Copyright 2015, Kenneth MacKay. Licensed under the BSD 2-clause license. */ + +#ifndef _UECC_ASM_ARM_MULT_SQUARE_H_ +#define _UECC_ASM_ARM_MULT_SQUARE_H_ + +#define FAST_MULT_ASM_5 \ + "add r0, 12 \n\t" \ + "add r2, 12 \n\t" \ + "ldmia r1!, {r3,r4} \n\t" \ + "ldmia r2!, {r6,r7} \n\t" \ + \ + "umull r11, r12, r3, r6 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r11, r9, r3, r7 \n\t" \ + "adds r12, r11 \n\t" \ + "adc r9, #0 \n\t" \ + "umull r11, r14, r4, r6 \n\t" \ + "adds r12, r11 \n\t" \ + "adcs r9, r14 \n\t" \ + "adc r10, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "umull r12, r14, r4, r7 \n\t" \ + "adds r9, r12 \n\t" \ + "adc r10, r14 \n\t" \ + "stmia r0!, {r9, r10} \n\t" \ + \ + "sub r0, 28 \n\t" \ + "sub r2, 20 \n\t" \ + "ldmia r2!, {r6,r7,r8} \n\t" \ + "ldmia r1!, {r5} \n\t" \ + \ + "umull r11, r12, r3, r6 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r11, r9, r3, r7 \n\t" \ + "adds r12, r11 \n\t" \ + "adc r9, #0 \n\t" \ + "umull r11, r14, r4, r6 \n\t" \ + "adds r12, r11 \n\t" \ + "adcs r9, r14 \n\t" \ + "adc r10, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "mov r11, #0 \n\t" \ + "umull r12, r14, r3, r8 \n\t" \ + "adds r9, r12 \n\t" \ + "adcs r10, r14 \n\t" \ + "adc r11, #0 \n\t" \ + "umull r12, r14, r4, r7 \n\t" \ + "adds r9, r12 \n\t" \ + "adcs r10, r14 \n\t" \ + "adc r11, #0 \n\t" \ + "umull r12, r14, r5, r6 \n\t" \ + "adds r9, r12 \n\t" \ + "adcs r10, r14 \n\t" \ + "adc r11, #0 \n\t" \ + "stmia r0!, {r9} \n\t" \ + \ + "ldmia r1!, {r3} \n\t" \ + "mov r12, #0 \n\t" \ + "umull r14, r9, r4, r8 \n\t" \ + "adds r10, r14 \n\t" \ + "adcs r11, r9 \n\t" \ + "adc r12, #0 \n\t" \ + "umull r14, r9, r5, r7 \n\t" \ + "adds r10, r14 \n\t" \ + "adcs r11, r9 \n\t" \ + "adc r12, #0 \n\t" \ + "umull r14, r9, r3, r6 \n\t" \ + "adds r10, r14 \n\t" \ + "adcs r11, r9 \n\t" \ + "adc r12, #0 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adds r10, r14 \n\t" \ + "adcs r11, #0 \n\t" \ + "adc r12, #0 \n\t" \ + "stmia r0!, {r10} \n\t" \ + \ + "ldmia r1!, {r4} \n\t" \ + "mov r14, #0 \n\t" \ + "umull r9, r10, r5, r8 \n\t" \ + "adds r11, r9 \n\t" \ + "adcs r12, r10 \n\t" \ + "adc r14, #0 \n\t" \ + "umull r9, r10, r3, r7 \n\t" \ + "adds r11, r9 \n\t" \ + "adcs r12, r10 \n\t" \ + "adc r14, #0 \n\t" \ + "umull r9, r10, r4, r6 \n\t" \ + "adds r11, r9 \n\t" \ + "adcs r12, r10 \n\t" \ + "adc r14, #0 \n\t" \ + "ldr r9, [r0] \n\t" \ + "adds r11, r9 \n\t" \ + "adcs r12, #0 \n\t" \ + "adc r14, #0 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "ldmia r2!, {r6} \n\t" \ + "mov r9, #0 \n\t" \ + "umull r10, r11, r5, r6 \n\t" \ + "adds r12, r10 \n\t" \ + "adcs r14, r11 \n\t" \ + "adc r9, #0 \n\t" \ + "umull r10, r11, r3, r8 \n\t" \ + "adds r12, r10 \n\t" \ + "adcs r14, r11 \n\t" \ + "adc r9, #0 \n\t" \ + "umull r10, r11, r4, r7 \n\t" \ + "adds r12, r10 \n\t" \ + "adcs r14, r11 \n\t" \ + "adc r9, #0 \n\t" \ + "ldr r10, [r0] \n\t" \ + "adds r12, r10 \n\t" \ + "adcs r14, #0 \n\t" \ + "adc r9, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "ldmia r2!, {r7} \n\t" \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r14, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "umull r11, r12, r3, r6 \n\t" \ + "adds r14, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r14, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "ldr r11, [r0] \n\t" \ + "adds r14, r11 \n\t" \ + "adcs r9, #0 \n\t" \ + "adc r10, #0 \n\t" \ + "stmia r0!, {r14} \n\t" \ + \ + "mov r11, #0 \n\t" \ + "umull r12, r14, r3, r7 \n\t" \ + "adds r9, r12 \n\t" \ + "adcs r10, r14 \n\t" \ + "adc r11, #0 \n\t" \ + "umull r12, r14, r4, r6 \n\t" \ + "adds r9, r12 \n\t" \ + "adcs r10, r14 \n\t" \ + "adc r11, #0 \n\t" \ + "stmia r0!, {r9} \n\t" \ + \ + "umull r14, r9, r4, r7 \n\t" \ + "adds r10, r14 \n\t" \ + "adc r11, r9 \n\t" \ + "stmia r0!, {r10, r11} \n\t" + +#define FAST_MULT_ASM_6 \ + "add r0, 12 \n\t" \ + "add r2, 12 \n\t" \ + "ldmia r1!, {r3,r4,r5} \n\t" \ + "ldmia r2!, {r6,r7,r8} \n\t" \ + \ + "umull r11, r12, r3, r6 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r11, r9, r3, r7 \n\t" \ + "adds r12, r11 \n\t" \ + "adc r9, #0 \n\t" \ + "umull r11, r14, r4, r6 \n\t" \ + "adds r12, r11 \n\t" \ + "adcs r9, r14 \n\t" \ + "adc r10, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "mov r11, #0 \n\t" \ + "umull r12, r14, r3, r8 \n\t" \ + "adds r9, r12 \n\t" \ + "adcs r10, r14 \n\t" \ + "adc r11, #0 \n\t" \ + "umull r12, r14, r4, r7 \n\t" \ + "adds r9, r12 \n\t" \ + "adcs r10, r14 \n\t" \ + "adc r11, #0 \n\t" \ + "umull r12, r14, r5, r6 \n\t" \ + "adds r9, r12 \n\t" \ + "adcs r10, r14 \n\t" \ + "adc r11, #0 \n\t" \ + "stmia r0!, {r9} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r14, r9, r4, r8 \n\t" \ + "adds r10, r14 \n\t" \ + "adcs r11, r9 \n\t" \ + "adc r12, #0 \n\t" \ + "umull r14, r9, r5, r7 \n\t" \ + "adds r10, r14 \n\t" \ + "adcs r11, r9 \n\t" \ + "adc r12, #0 \n\t" \ + "stmia r0!, {r10} \n\t" \ + \ + "umull r9, r10, r5, r8 \n\t" \ + "adds r11, r9 \n\t" \ + "adc r12, r10 \n\t" \ + "stmia r0!, {r11, r12} \n\t" \ + \ + "sub r0, 36 \n\t" \ + "sub r2, 24 \n\t" \ + "ldmia r2!, {r6,r7,r8} \n\t" \ + \ + "umull r11, r12, r3, r6 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r11, r9, r3, r7 \n\t" \ + "adds r12, r11 \n\t" \ + "adc r9, #0 \n\t" \ + "umull r11, r14, r4, r6 \n\t" \ + "adds r12, r11 \n\t" \ + "adcs r9, r14 \n\t" \ + "adc r10, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "mov r11, #0 \n\t" \ + "umull r12, r14, r3, r8 \n\t" \ + "adds r9, r12 \n\t" \ + "adcs r10, r14 \n\t" \ + "adc r11, #0 \n\t" \ + "umull r12, r14, r4, r7 \n\t" \ + "adds r9, r12 \n\t" \ + "adcs r10, r14 \n\t" \ + "adc r11, #0 \n\t" \ + "umull r12, r14, r5, r6 \n\t" \ + "adds r9, r12 \n\t" \ + "adcs r10, r14 \n\t" \ + "adc r11, #0 \n\t" \ + "stmia r0!, {r9} \n\t" \ + \ + "ldmia r1!, {r3} \n\t" \ + "mov r12, #0 \n\t" \ + "umull r14, r9, r4, r8 \n\t" \ + "adds r10, r14 \n\t" \ + "adcs r11, r9 \n\t" \ + "adc r12, #0 \n\t" \ + "umull r14, r9, r5, r7 \n\t" \ + "adds r10, r14 \n\t" \ + "adcs r11, r9 \n\t" \ + "adc r12, #0 \n\t" \ + "umull r14, r9, r3, r6 \n\t" \ + "adds r10, r14 \n\t" \ + "adcs r11, r9 \n\t" \ + "adc r12, #0 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adds r10, r14 \n\t" \ + "adcs r11, #0 \n\t" \ + "adc r12, #0 \n\t" \ + "stmia r0!, {r10} \n\t" \ + \ + "ldmia r1!, {r4} \n\t" \ + "mov r14, #0 \n\t" \ + "umull r9, r10, r5, r8 \n\t" \ + "adds r11, r9 \n\t" \ + "adcs r12, r10 \n\t" \ + "adc r14, #0 \n\t" \ + "umull r9, r10, r3, r7 \n\t" \ + "adds r11, r9 \n\t" \ + "adcs r12, r10 \n\t" \ + "adc r14, #0 \n\t" \ + "umull r9, r10, r4, r6 \n\t" \ + "adds r11, r9 \n\t" \ + "adcs r12, r10 \n\t" \ + "adc r14, #0 \n\t" \ + "ldr r9, [r0] \n\t" \ + "adds r11, r9 \n\t" \ + "adcs r12, #0 \n\t" \ + "adc r14, #0 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "ldmia r1!, {r5} \n\t" \ + "mov r9, #0 \n\t" \ + "umull r10, r11, r3, r8 \n\t" \ + "adds r12, r10 \n\t" \ + "adcs r14, r11 \n\t" \ + "adc r9, #0 \n\t" \ + "umull r10, r11, r4, r7 \n\t" \ + "adds r12, r10 \n\t" \ + "adcs r14, r11 \n\t" \ + "adc r9, #0 \n\t" \ + "umull r10, r11, r5, r6 \n\t" \ + "adds r12, r10 \n\t" \ + "adcs r14, r11 \n\t" \ + "adc r9, #0 \n\t" \ + "ldr r10, [r0] \n\t" \ + "adds r12, r10 \n\t" \ + "adcs r14, #0 \n\t" \ + "adc r9, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "ldmia r2!, {r6} \n\t" \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r3, r6 \n\t" \ + "adds r14, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r14, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r14, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "ldr r11, [r0] \n\t" \ + "adds r14, r11 \n\t" \ + "adcs r9, #0 \n\t" \ + "adc r10, #0 \n\t" \ + "stmia r0!, {r14} \n\t" \ + \ + "ldmia r2!, {r7} \n\t" \ + "mov r11, #0 \n\t" \ + "umull r12, r14, r3, r7 \n\t" \ + "adds r9, r12 \n\t" \ + "adcs r10, r14 \n\t" \ + "adc r11, #0 \n\t" \ + "umull r12, r14, r4, r6 \n\t" \ + "adds r9, r12 \n\t" \ + "adcs r10, r14 \n\t" \ + "adc r11, #0 \n\t" \ + "umull r12, r14, r5, r8 \n\t" \ + "adds r9, r12 \n\t" \ + "adcs r10, r14 \n\t" \ + "adc r11, #0 \n\t" \ + "ldr r12, [r0] \n\t" \ + "adds r9, r12 \n\t" \ + "adcs r10, #0 \n\t" \ + "adc r11, #0 \n\t" \ + "stmia r0!, {r9} \n\t" \ + \ + "ldmia r2!, {r8} \n\t" \ + "mov r12, #0 \n\t" \ + "umull r14, r9, r3, r8 \n\t" \ + "adds r10, r14 \n\t" \ + "adcs r11, r9 \n\t" \ + "adc r12, #0 \n\t" \ + "umull r14, r9, r4, r7 \n\t" \ + "adds r10, r14 \n\t" \ + "adcs r11, r9 \n\t" \ + "adc r12, #0 \n\t" \ + "umull r14, r9, r5, r6 \n\t" \ + "adds r10, r14 \n\t" \ + "adcs r11, r9 \n\t" \ + "adc r12, #0 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adds r10, r14 \n\t" \ + "adcs r11, #0 \n\t" \ + "adc r12, #0 \n\t" \ + "stmia r0!, {r10} \n\t" \ + \ + "mov r14, #0 \n\t" \ + "umull r9, r10, r4, r8 \n\t" \ + "adds r11, r9 \n\t" \ + "adcs r12, r10 \n\t" \ + "adc r14, #0 \n\t" \ + "umull r9, r10, r5, r7 \n\t" \ + "adds r11, r9 \n\t" \ + "adcs r12, r10 \n\t" \ + "adc r14, #0 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "umull r10, r11, r5, r8 \n\t" \ + "adds r12, r10 \n\t" \ + "adc r14, r11 \n\t" \ + "stmia r0!, {r12, r14} \n\t" + +#define FAST_MULT_ASM_7 \ + "add r0, 24 \n\t" \ + "add r2, 24 \n\t" \ + "ldmia r1!, {r3} \n\t" \ + "ldmia r2!, {r6} \n\t" \ + \ + "umull r9, r10, r3, r6 \n\t" \ + "stmia r0!, {r9, r10} \n\t" \ + \ + "sub r0, 20 \n\t" \ + "sub r2, 16 \n\t" \ + "ldmia r2!, {r6, r7, r8} \n\t" \ + "ldmia r1!, {r4, r5} \n\t" \ + \ + "umull r9, r10, r3, r6 \n\t" \ + "stmia r0!, {r9} \n\t" \ + \ + "mov r14, #0 \n\t" \ + "umull r9, r12, r3, r7 \n\t" \ + "adds r10, r9 \n\t" \ + "adc r12, #0 \n\t" \ + "umull r9, r11, r4, r6 \n\t" \ + "adds r10, r9 \n\t" \ + "adcs r12, r11 \n\t" \ + "adc r14, #0 \n\t" \ + "stmia r0!, {r10} \n\t" \ + \ + "mov r9, #0 \n\t" \ + "umull r10, r11, r3, r8 \n\t" \ + "adds r12, r10 \n\t" \ + "adcs r14, r11 \n\t" \ + "adc r9, #0 \n\t" \ + "umull r10, r11, r4, r7 \n\t" \ + "adds r12, r10 \n\t" \ + "adcs r14, r11 \n\t" \ + "adc r9, #0 \n\t" \ + "umull r10, r11, r5, r6 \n\t" \ + "adds r12, r10 \n\t" \ + "adcs r14, r11 \n\t" \ + "adc r9, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "ldmia r1!, {r3} \n\t" \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r14, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r14, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "umull r11, r12, r3, r6 \n\t" \ + "adds r14, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "ldr r11, [r0] \n\t" \ + "adds r14, r11 \n\t" \ + "adcs r9, #0 \n\t" \ + "adc r10, #0 \n\t" \ + "stmia r0!, {r14} \n\t" \ + \ + "ldmia r2!, {r6} \n\t" \ + "mov r11, #0 \n\t" \ + "umull r12, r14, r4, r6 \n\t" \ + "adds r9, r12 \n\t" \ + "adcs r10, r14 \n\t" \ + "adc r11, #0 \n\t" \ + "umull r12, r14, r5, r8 \n\t" \ + "adds r9, r12 \n\t" \ + "adcs r10, r14 \n\t" \ + "adc r11, #0 \n\t" \ + "umull r12, r14, r3, r7 \n\t" \ + "adds r9, r12 \n\t" \ + "adcs r10, r14 \n\t" \ + "adc r11, #0 \n\t" \ + "ldr r12, [r0] \n\t" \ + "adds r9, r12 \n\t" \ + "adcs r10, #0 \n\t" \ + "adc r11, #0 \n\t" \ + "stmia r0!, {r9} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r14, r9, r5, r6 \n\t" \ + "adds r10, r14 \n\t" \ + "adcs r11, r9 \n\t" \ + "adc r12, #0 \n\t" \ + "umull r14, r9, r3, r8 \n\t" \ + "adds r10, r14 \n\t" \ + "adcs r11, r9 \n\t" \ + "adc r12, #0 \n\t" \ + "stmia r0!, {r10} \n\t" \ + \ + "umull r9, r10, r3, r6 \n\t" \ + "adds r11, r9 \n\t" \ + "adc r12, r10 \n\t" \ + "stmia r0!, {r11, r12} \n\t" \ + \ + "sub r0, 44 \n\t" \ + "sub r1, 16 \n\t" \ + "sub r2, 28 \n\t" \ + "ldmia r1!, {r3,r4,r5} \n\t" \ + "ldmia r2!, {r6,r7,r8} \n\t" \ + \ + "umull r9, r10, r3, r6 \n\t" \ + "stmia r0!, {r9} \n\t" \ + \ + "mov r14, #0 \n\t" \ + "umull r9, r12, r3, r7 \n\t" \ + "adds r10, r9 \n\t" \ + "adc r12, #0 \n\t" \ + "umull r9, r11, r4, r6 \n\t" \ + "adds r10, r9 \n\t" \ + "adcs r12, r11 \n\t" \ + "adc r14, #0 \n\t" \ + "stmia r0!, {r10} \n\t" \ + \ + "mov r9, #0 \n\t" \ + "umull r10, r11, r3, r8 \n\t" \ + "adds r12, r10 \n\t" \ + "adcs r14, r11 \n\t" \ + "adc r9, #0 \n\t" \ + "umull r10, r11, r4, r7 \n\t" \ + "adds r12, r10 \n\t" \ + "adcs r14, r11 \n\t" \ + "adc r9, #0 \n\t" \ + "umull r10, r11, r5, r6 \n\t" \ + "adds r12, r10 \n\t" \ + "adcs r14, r11 \n\t" \ + "adc r9, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "ldmia r1!, {r3} \n\t" \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r14, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r14, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "umull r11, r12, r3, r6 \n\t" \ + "adds r14, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "ldr r11, [r0] \n\t" \ + "adds r14, r11 \n\t" \ + "adcs r9, #0 \n\t" \ + "adc r10, #0 \n\t" \ + "stmia r0!, {r14} \n\t" \ + \ + "ldmia r1!, {r4} \n\t" \ + "mov r11, #0 \n\t" \ + "umull r12, r14, r5, r8 \n\t" \ + "adds r9, r12 \n\t" \ + "adcs r10, r14 \n\t" \ + "adc r11, #0 \n\t" \ + "umull r12, r14, r3, r7 \n\t" \ + "adds r9, r12 \n\t" \ + "adcs r10, r14 \n\t" \ + "adc r11, #0 \n\t" \ + "umull r12, r14, r4, r6 \n\t" \ + "adds r9, r12 \n\t" \ + "adcs r10, r14 \n\t" \ + "adc r11, #0 \n\t" \ + "ldr r12, [r0] \n\t" \ + "adds r9, r12 \n\t" \ + "adcs r10, #0 \n\t" \ + "adc r11, #0 \n\t" \ + "stmia r0!, {r9} \n\t" \ + \ + "ldmia r1!, {r5} \n\t" \ + "mov r12, #0 \n\t" \ + "umull r14, r9, r3, r8 \n\t" \ + "adds r10, r14 \n\t" \ + "adcs r11, r9 \n\t" \ + "adc r12, #0 \n\t" \ + "umull r14, r9, r4, r7 \n\t" \ + "adds r10, r14 \n\t" \ + "adcs r11, r9 \n\t" \ + "adc r12, #0 \n\t" \ + "umull r14, r9, r5, r6 \n\t" \ + "adds r10, r14 \n\t" \ + "adcs r11, r9 \n\t" \ + "adc r12, #0 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adds r10, r14 \n\t" \ + "adcs r11, #0 \n\t" \ + "adc r12, #0 \n\t" \ + "stmia r0!, {r10} \n\t" \ + \ + "ldmia r1!, {r3} \n\t" \ + "mov r14, #0 \n\t" \ + "umull r9, r10, r4, r8 \n\t" \ + "adds r11, r9 \n\t" \ + "adcs r12, r10 \n\t" \ + "adc r14, #0 \n\t" \ + "umull r9, r10, r5, r7 \n\t" \ + "adds r11, r9 \n\t" \ + "adcs r12, r10 \n\t" \ + "adc r14, #0 \n\t" \ + "umull r9, r10, r3, r6 \n\t" \ + "adds r11, r9 \n\t" \ + "adcs r12, r10 \n\t" \ + "adc r14, #0 \n\t" \ + "ldr r9, [r0] \n\t" \ + "adds r11, r9 \n\t" \ + "adcs r12, #0 \n\t" \ + "adc r14, #0 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "ldmia r2!, {r6} \n\t" \ + "mov r9, #0 \n\t" \ + "umull r10, r11, r4, r6 \n\t" \ + "adds r12, r10 \n\t" \ + "adcs r14, r11 \n\t" \ + "adc r9, #0 \n\t" \ + "umull r10, r11, r5, r8 \n\t" \ + "adds r12, r10 \n\t" \ + "adcs r14, r11 \n\t" \ + "adc r9, #0 \n\t" \ + "umull r10, r11, r3, r7 \n\t" \ + "adds r12, r10 \n\t" \ + "adcs r14, r11 \n\t" \ + "adc r9, #0 \n\t" \ + "ldr r10, [r0] \n\t" \ + "adds r12, r10 \n\t" \ + "adcs r14, #0 \n\t" \ + "adc r9, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "ldmia r2!, {r7} \n\t" \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r4, r7 \n\t" \ + "adds r14, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "umull r11, r12, r5, r6 \n\t" \ + "adds r14, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "umull r11, r12, r3, r8 \n\t" \ + "adds r14, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "ldr r11, [r0] \n\t" \ + "adds r14, r11 \n\t" \ + "adcs r9, #0 \n\t" \ + "adc r10, #0 \n\t" \ + "stmia r0!, {r14} \n\t" \ + \ + "ldmia r2!, {r8} \n\t" \ + "mov r11, #0 \n\t" \ + "umull r12, r14, r4, r8 \n\t" \ + "adds r9, r12 \n\t" \ + "adcs r10, r14 \n\t" \ + "adc r11, #0 \n\t" \ + "umull r12, r14, r5, r7 \n\t" \ + "adds r9, r12 \n\t" \ + "adcs r10, r14 \n\t" \ + "adc r11, #0 \n\t" \ + "umull r12, r14, r3, r6 \n\t" \ + "adds r9, r12 \n\t" \ + "adcs r10, r14 \n\t" \ + "adc r11, #0 \n\t" \ + "ldr r12, [r0] \n\t" \ + "adds r9, r12 \n\t" \ + "adcs r10, #0 \n\t" \ + "adc r11, #0 \n\t" \ + "stmia r0!, {r9} \n\t" \ + \ + "ldmia r2!, {r6} \n\t" \ + "mov r12, #0 \n\t" \ + "umull r14, r9, r4, r6 \n\t" \ + "adds r10, r14 \n\t" \ + "adcs r11, r9 \n\t" \ + "adc r12, #0 \n\t" \ + "umull r14, r9, r5, r8 \n\t" \ + "adds r10, r14 \n\t" \ + "adcs r11, r9 \n\t" \ + "adc r12, #0 \n\t" \ + "umull r14, r9, r3, r7 \n\t" \ + "adds r10, r14 \n\t" \ + "adcs r11, r9 \n\t" \ + "adc r12, #0 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adds r10, r14 \n\t" \ + "adcs r11, #0 \n\t" \ + "adc r12, #0 \n\t" \ + "stmia r0!, {r10} \n\t" \ + \ + "mov r14, #0 \n\t" \ + "umull r9, r10, r5, r6 \n\t" \ + "adds r11, r9 \n\t" \ + "adcs r12, r10 \n\t" \ + "adc r14, #0 \n\t" \ + "umull r9, r10, r3, r8 \n\t" \ + "adds r11, r9 \n\t" \ + "adcs r12, r10 \n\t" \ + "adc r14, #0 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "umull r10, r11, r3, r6 \n\t" \ + "adds r12, r10 \n\t" \ + "adc r14, r11 \n\t" \ + "stmia r0!, {r12, r14} \n\t" + +#define FAST_MULT_ASM_8 \ + "add r0, 24 \n\t" \ + "add r2, 24 \n\t" \ + "ldmia r1!, {r3,r4} \n\t" \ + "ldmia r2!, {r6,r7} \n\t" \ + \ + "umull r11, r12, r3, r6 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r11, r9, r3, r7 \n\t" \ + "adds r12, r11 \n\t" \ + "adc r9, #0 \n\t" \ + "umull r11, r14, r4, r6 \n\t" \ + "adds r12, r11 \n\t" \ + "adcs r9, r14 \n\t" \ + "adc r10, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "umull r12, r14, r4, r7 \n\t" \ + "adds r9, r12 \n\t" \ + "adc r10, r14 \n\t" \ + "stmia r0!, {r9, r10} \n\t" \ + \ + "sub r0, 28 \n\t" \ + "sub r2, 20 \n\t" \ + "ldmia r2!, {r6,r7,r8} \n\t" \ + "ldmia r1!, {r5} \n\t" \ + \ + "umull r11, r12, r3, r6 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r11, r9, r3, r7 \n\t" \ + "adds r12, r11 \n\t" \ + "adc r9, #0 \n\t" \ + "umull r11, r14, r4, r6 \n\t" \ + "adds r12, r11 \n\t" \ + "adcs r9, r14 \n\t" \ + "adc r10, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "mov r11, #0 \n\t" \ + "umull r12, r14, r3, r8 \n\t" \ + "adds r9, r12 \n\t" \ + "adcs r10, r14 \n\t" \ + "adc r11, #0 \n\t" \ + "umull r12, r14, r4, r7 \n\t" \ + "adds r9, r12 \n\t" \ + "adcs r10, r14 \n\t" \ + "adc r11, #0 \n\t" \ + "umull r12, r14, r5, r6 \n\t" \ + "adds r9, r12 \n\t" \ + "adcs r10, r14 \n\t" \ + "adc r11, #0 \n\t" \ + "stmia r0!, {r9} \n\t" \ + \ + "ldmia r1!, {r3} \n\t" \ + "mov r12, #0 \n\t" \ + "umull r14, r9, r4, r8 \n\t" \ + "adds r10, r14 \n\t" \ + "adcs r11, r9 \n\t" \ + "adc r12, #0 \n\t" \ + "umull r14, r9, r5, r7 \n\t" \ + "adds r10, r14 \n\t" \ + "adcs r11, r9 \n\t" \ + "adc r12, #0 \n\t" \ + "umull r14, r9, r3, r6 \n\t" \ + "adds r10, r14 \n\t" \ + "adcs r11, r9 \n\t" \ + "adc r12, #0 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adds r10, r14 \n\t" \ + "adcs r11, #0 \n\t" \ + "adc r12, #0 \n\t" \ + "stmia r0!, {r10} \n\t" \ + \ + "ldmia r1!, {r4} \n\t" \ + "mov r14, #0 \n\t" \ + "umull r9, r10, r5, r8 \n\t" \ + "adds r11, r9 \n\t" \ + "adcs r12, r10 \n\t" \ + "adc r14, #0 \n\t" \ + "umull r9, r10, r3, r7 \n\t" \ + "adds r11, r9 \n\t" \ + "adcs r12, r10 \n\t" \ + "adc r14, #0 \n\t" \ + "umull r9, r10, r4, r6 \n\t" \ + "adds r11, r9 \n\t" \ + "adcs r12, r10 \n\t" \ + "adc r14, #0 \n\t" \ + "ldr r9, [r0] \n\t" \ + "adds r11, r9 \n\t" \ + "adcs r12, #0 \n\t" \ + "adc r14, #0 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "ldmia r2!, {r6} \n\t" \ + "mov r9, #0 \n\t" \ + "umull r10, r11, r5, r6 \n\t" \ + "adds r12, r10 \n\t" \ + "adcs r14, r11 \n\t" \ + "adc r9, #0 \n\t" \ + "umull r10, r11, r3, r8 \n\t" \ + "adds r12, r10 \n\t" \ + "adcs r14, r11 \n\t" \ + "adc r9, #0 \n\t" \ + "umull r10, r11, r4, r7 \n\t" \ + "adds r12, r10 \n\t" \ + "adcs r14, r11 \n\t" \ + "adc r9, #0 \n\t" \ + "ldr r10, [r0] \n\t" \ + "adds r12, r10 \n\t" \ + "adcs r14, #0 \n\t" \ + "adc r9, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "ldmia r2!, {r7} \n\t" \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r14, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "umull r11, r12, r3, r6 \n\t" \ + "adds r14, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r14, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "ldr r11, [r0] \n\t" \ + "adds r14, r11 \n\t" \ + "adcs r9, #0 \n\t" \ + "adc r10, #0 \n\t" \ + "stmia r0!, {r14} \n\t" \ + \ + "mov r11, #0 \n\t" \ + "umull r12, r14, r3, r7 \n\t" \ + "adds r9, r12 \n\t" \ + "adcs r10, r14 \n\t" \ + "adc r11, #0 \n\t" \ + "umull r12, r14, r4, r6 \n\t" \ + "adds r9, r12 \n\t" \ + "adcs r10, r14 \n\t" \ + "adc r11, #0 \n\t" \ + "stmia r0!, {r9} \n\t" \ + \ + "umull r14, r9, r4, r7 \n\t" \ + "adds r10, r14 \n\t" \ + "adc r11, r9 \n\t" \ + "stmia r0!, {r10, r11} \n\t" \ + \ + "sub r0, 52 \n\t" \ + "sub r1, 20 \n\t" \ + "sub r2, 32 \n\t" \ + "ldmia r1!, {r3,r4,r5} \n\t" \ + "ldmia r2!, {r6,r7,r8} \n\t" \ + \ + "umull r11, r12, r3, r6 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r11, r9, r3, r7 \n\t" \ + "adds r12, r11 \n\t" \ + "adc r9, #0 \n\t" \ + "umull r11, r14, r4, r6 \n\t" \ + "adds r12, r11 \n\t" \ + "adcs r9, r14 \n\t" \ + "adc r10, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "mov r11, #0 \n\t" \ + "umull r12, r14, r3, r8 \n\t" \ + "adds r9, r12 \n\t" \ + "adcs r10, r14 \n\t" \ + "adc r11, #0 \n\t" \ + "umull r12, r14, r4, r7 \n\t" \ + "adds r9, r12 \n\t" \ + "adcs r10, r14 \n\t" \ + "adc r11, #0 \n\t" \ + "umull r12, r14, r5, r6 \n\t" \ + "adds r9, r12 \n\t" \ + "adcs r10, r14 \n\t" \ + "adc r11, #0 \n\t" \ + "stmia r0!, {r9} \n\t" \ + \ + "ldmia r1!, {r3} \n\t" \ + "mov r12, #0 \n\t" \ + "umull r14, r9, r4, r8 \n\t" \ + "adds r10, r14 \n\t" \ + "adcs r11, r9 \n\t" \ + "adc r12, #0 \n\t" \ + "umull r14, r9, r5, r7 \n\t" \ + "adds r10, r14 \n\t" \ + "adcs r11, r9 \n\t" \ + "adc r12, #0 \n\t" \ + "umull r14, r9, r3, r6 \n\t" \ + "adds r10, r14 \n\t" \ + "adcs r11, r9 \n\t" \ + "adc r12, #0 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adds r10, r14 \n\t" \ + "adcs r11, #0 \n\t" \ + "adc r12, #0 \n\t" \ + "stmia r0!, {r10} \n\t" \ + \ + "ldmia r1!, {r4} \n\t" \ + "mov r14, #0 \n\t" \ + "umull r9, r10, r5, r8 \n\t" \ + "adds r11, r9 \n\t" \ + "adcs r12, r10 \n\t" \ + "adc r14, #0 \n\t" \ + "umull r9, r10, r3, r7 \n\t" \ + "adds r11, r9 \n\t" \ + "adcs r12, r10 \n\t" \ + "adc r14, #0 \n\t" \ + "umull r9, r10, r4, r6 \n\t" \ + "adds r11, r9 \n\t" \ + "adcs r12, r10 \n\t" \ + "adc r14, #0 \n\t" \ + "ldr r9, [r0] \n\t" \ + "adds r11, r9 \n\t" \ + "adcs r12, #0 \n\t" \ + "adc r14, #0 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "ldmia r1!, {r5} \n\t" \ + "mov r9, #0 \n\t" \ + "umull r10, r11, r3, r8 \n\t" \ + "adds r12, r10 \n\t" \ + "adcs r14, r11 \n\t" \ + "adc r9, #0 \n\t" \ + "umull r10, r11, r4, r7 \n\t" \ + "adds r12, r10 \n\t" \ + "adcs r14, r11 \n\t" \ + "adc r9, #0 \n\t" \ + "umull r10, r11, r5, r6 \n\t" \ + "adds r12, r10 \n\t" \ + "adcs r14, r11 \n\t" \ + "adc r9, #0 \n\t" \ + "ldr r10, [r0] \n\t" \ + "adds r12, r10 \n\t" \ + "adcs r14, #0 \n\t" \ + "adc r9, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "ldmia r1!, {r3} \n\t" \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r14, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r14, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "umull r11, r12, r3, r6 \n\t" \ + "adds r14, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "ldr r11, [r0] \n\t" \ + "adds r14, r11 \n\t" \ + "adcs r9, #0 \n\t" \ + "adc r10, #0 \n\t" \ + "stmia r0!, {r14} \n\t" \ + \ + "ldmia r1!, {r4} \n\t" \ + "mov r11, #0 \n\t" \ + "umull r12, r14, r5, r8 \n\t" \ + "adds r9, r12 \n\t" \ + "adcs r10, r14 \n\t" \ + "adc r11, #0 \n\t" \ + "umull r12, r14, r3, r7 \n\t" \ + "adds r9, r12 \n\t" \ + "adcs r10, r14 \n\t" \ + "adc r11, #0 \n\t" \ + "umull r12, r14, r4, r6 \n\t" \ + "adds r9, r12 \n\t" \ + "adcs r10, r14 \n\t" \ + "adc r11, #0 \n\t" \ + "ldr r12, [r0] \n\t" \ + "adds r9, r12 \n\t" \ + "adcs r10, #0 \n\t" \ + "adc r11, #0 \n\t" \ + "stmia r0!, {r9} \n\t" \ + \ + "ldmia r2!, {r6} \n\t" \ + "mov r12, #0 \n\t" \ + "umull r14, r9, r5, r6 \n\t" \ + "adds r10, r14 \n\t" \ + "adcs r11, r9 \n\t" \ + "adc r12, #0 \n\t" \ + "umull r14, r9, r3, r8 \n\t" \ + "adds r10, r14 \n\t" \ + "adcs r11, r9 \n\t" \ + "adc r12, #0 \n\t" \ + "umull r14, r9, r4, r7 \n\t" \ + "adds r10, r14 \n\t" \ + "adcs r11, r9 \n\t" \ + "adc r12, #0 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adds r10, r14 \n\t" \ + "adcs r11, #0 \n\t" \ + "adc r12, #0 \n\t" \ + "stmia r0!, {r10} \n\t" \ + \ + "ldmia r2!, {r7} \n\t" \ + "mov r14, #0 \n\t" \ + "umull r9, r10, r5, r7 \n\t" \ + "adds r11, r9 \n\t" \ + "adcs r12, r10 \n\t" \ + "adc r14, #0 \n\t" \ + "umull r9, r10, r3, r6 \n\t" \ + "adds r11, r9 \n\t" \ + "adcs r12, r10 \n\t" \ + "adc r14, #0 \n\t" \ + "umull r9, r10, r4, r8 \n\t" \ + "adds r11, r9 \n\t" \ + "adcs r12, r10 \n\t" \ + "adc r14, #0 \n\t" \ + "ldr r9, [r0] \n\t" \ + "adds r11, r9 \n\t" \ + "adcs r12, #0 \n\t" \ + "adc r14, #0 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "ldmia r2!, {r8} \n\t" \ + "mov r9, #0 \n\t" \ + "umull r10, r11, r5, r8 \n\t" \ + "adds r12, r10 \n\t" \ + "adcs r14, r11 \n\t" \ + "adc r9, #0 \n\t" \ + "umull r10, r11, r3, r7 \n\t" \ + "adds r12, r10 \n\t" \ + "adcs r14, r11 \n\t" \ + "adc r9, #0 \n\t" \ + "umull r10, r11, r4, r6 \n\t" \ + "adds r12, r10 \n\t" \ + "adcs r14, r11 \n\t" \ + "adc r9, #0 \n\t" \ + "ldr r10, [r0] \n\t" \ + "adds r12, r10 \n\t" \ + "adcs r14, #0 \n\t" \ + "adc r9, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "ldmia r2!, {r6} \n\t" \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r5, r6 \n\t" \ + "adds r14, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "umull r11, r12, r3, r8 \n\t" \ + "adds r14, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "umull r11, r12, r4, r7 \n\t" \ + "adds r14, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "ldr r11, [r0] \n\t" \ + "adds r14, r11 \n\t" \ + "adcs r9, #0 \n\t" \ + "adc r10, #0 \n\t" \ + "stmia r0!, {r14} \n\t" \ + \ + "ldmia r2!, {r7} \n\t" \ + "mov r11, #0 \n\t" \ + "umull r12, r14, r5, r7 \n\t" \ + "adds r9, r12 \n\t" \ + "adcs r10, r14 \n\t" \ + "adc r11, #0 \n\t" \ + "umull r12, r14, r3, r6 \n\t" \ + "adds r9, r12 \n\t" \ + "adcs r10, r14 \n\t" \ + "adc r11, #0 \n\t" \ + "umull r12, r14, r4, r8 \n\t" \ + "adds r9, r12 \n\t" \ + "adcs r10, r14 \n\t" \ + "adc r11, #0 \n\t" \ + "ldr r12, [r0] \n\t" \ + "adds r9, r12 \n\t" \ + "adcs r10, #0 \n\t" \ + "adc r11, #0 \n\t" \ + "stmia r0!, {r9} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r14, r9, r3, r7 \n\t" \ + "adds r10, r14 \n\t" \ + "adcs r11, r9 \n\t" \ + "adc r12, #0 \n\t" \ + "umull r14, r9, r4, r6 \n\t" \ + "adds r10, r14 \n\t" \ + "adcs r11, r9 \n\t" \ + "adc r12, #0 \n\t" \ + "stmia r0!, {r10} \n\t" \ + \ + "umull r9, r10, r4, r7 \n\t" \ + "adds r11, r9 \n\t" \ + "adc r12, r10 \n\t" \ + "stmia r0!, {r11, r12} \n\t" + +#define FAST_SQUARE_ASM_5 \ + "ldmia r1!, {r2,r3,r4,r5,r6} \n\t" \ + \ + "umull r11, r12, r2, r2 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "mov r9, #0 \n\t" \ + "umull r10, r11, r2, r3 \n\t" \ + "adds r12, r10 \n\t" \ + "adcs r8, r11, #0 \n\t" \ + "adc r9, #0 \n\t" \ + "adds r12, r10 \n\t" \ + "adcs r8, r11 \n\t" \ + "adc r9, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r2, r4 \n\t" \ + "adds r11, r11 \n\t" \ + "adcs r12, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "adds r8, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "umull r11, r12, r3, r3 \n\t" \ + "adds r8, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r8, r11, r2, r5 \n\t" \ + "umull r1, r14, r3, r4 \n\t" \ + "adds r8, r1 \n\t" \ + "adcs r11, r14 \n\t" \ + "adc r12, #0 \n\t" \ + "adds r8, r8 \n\t" \ + "adcs r11, r11 \n\t" \ + "adc r12, r12 \n\t" \ + "adds r8, r9 \n\t" \ + "adcs r11, r10 \n\t" \ + "adc r12, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r8, r9, r2, r6 \n\t" \ + "umull r1, r14, r3, r5 \n\t" \ + "adds r8, r1 \n\t" \ + "adcs r9, r14 \n\t" \ + "adc r10, #0 \n\t" \ + "adds r8, r8 \n\t" \ + "adcs r9, r9 \n\t" \ + "adc r10, r10 \n\t" \ + "umull r1, r14, r4, r4 \n\t" \ + "adds r8, r1 \n\t" \ + "adcs r9, r14 \n\t" \ + "adc r10, #0 \n\t" \ + "adds r8, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r8, r11, r3, r6 \n\t" \ + "umull r1, r14, r4, r5 \n\t" \ + "adds r8, r1 \n\t" \ + "adcs r11, r14 \n\t" \ + "adc r12, #0 \n\t" \ + "adds r8, r8 \n\t" \ + "adcs r11, r11 \n\t" \ + "adc r12, r12 \n\t" \ + "adds r8, r9 \n\t" \ + "adcs r11, r10 \n\t" \ + "adc r12, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r8, #0 \n\t" \ + "umull r1, r10, r4, r6 \n\t" \ + "adds r1, r1 \n\t" \ + "adcs r10, r10 \n\t" \ + "adc r8, #0 \n\t" \ + "adds r11, r1 \n\t" \ + "adcs r12, r10 \n\t" \ + "adc r8, #0 \n\t" \ + "umull r1, r10, r5, r5 \n\t" \ + "adds r11, r1 \n\t" \ + "adcs r12, r10 \n\t" \ + "adc r8, #0 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "mov r11, #0 \n\t" \ + "umull r1, r10, r5, r6 \n\t" \ + "adds r1, r1 \n\t" \ + "adcs r10, r10 \n\t" \ + "adc r11, #0 \n\t" \ + "adds r12, r1 \n\t" \ + "adcs r8, r10 \n\t" \ + "adc r11, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "umull r1, r10, r6, r6 \n\t" \ + "adds r8, r1 \n\t" \ + "adcs r11, r10 \n\t" \ + "stmia r0!, {r8, r11} \n\t" + +#define FAST_SQUARE_ASM_6 \ + "ldmia r1!, {r2,r3,r4,r5,r6,r7} \n\t" \ + \ + "umull r11, r12, r2, r2 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "mov r9, #0 \n\t" \ + "umull r10, r11, r2, r3 \n\t" \ + "adds r12, r10 \n\t" \ + "adcs r8, r11, #0 \n\t" \ + "adc r9, #0 \n\t" \ + "adds r12, r10 \n\t" \ + "adcs r8, r11 \n\t" \ + "adc r9, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r2, r4 \n\t" \ + "adds r11, r11 \n\t" \ + "adcs r12, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "adds r8, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "umull r11, r12, r3, r3 \n\t" \ + "adds r8, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r8, r11, r2, r5 \n\t" \ + "umull r1, r14, r3, r4 \n\t" \ + "adds r8, r1 \n\t" \ + "adcs r11, r14 \n\t" \ + "adc r12, #0 \n\t" \ + "adds r8, r8 \n\t" \ + "adcs r11, r11 \n\t" \ + "adc r12, r12 \n\t" \ + "adds r8, r9 \n\t" \ + "adcs r11, r10 \n\t" \ + "adc r12, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r8, r9, r2, r6 \n\t" \ + "umull r1, r14, r3, r5 \n\t" \ + "adds r8, r1 \n\t" \ + "adcs r9, r14 \n\t" \ + "adc r10, #0 \n\t" \ + "adds r8, r8 \n\t" \ + "adcs r9, r9 \n\t" \ + "adc r10, r10 \n\t" \ + "umull r1, r14, r4, r4 \n\t" \ + "adds r8, r1 \n\t" \ + "adcs r9, r14 \n\t" \ + "adc r10, #0 \n\t" \ + "adds r8, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r8, r11, r2, r7 \n\t" \ + "umull r1, r14, r3, r6 \n\t" \ + "adds r8, r1 \n\t" \ + "adcs r11, r14 \n\t" \ + "adc r12, #0 \n\t" \ + "umull r1, r14, r4, r5 \n\t" \ + "adds r8, r1 \n\t" \ + "adcs r11, r14 \n\t" \ + "adc r12, #0 \n\t" \ + "adds r8, r8 \n\t" \ + "adcs r11, r11 \n\t" \ + "adc r12, r12 \n\t" \ + "adds r8, r9 \n\t" \ + "adcs r11, r10 \n\t" \ + "adc r12, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r8, r9, r3, r7 \n\t" \ + "umull r1, r14, r4, r6 \n\t" \ + "adds r8, r1 \n\t" \ + "adcs r9, r14 \n\t" \ + "adc r10, #0 \n\t" \ + "adds r8, r8 \n\t" \ + "adcs r9, r9 \n\t" \ + "adc r10, r10 \n\t" \ + "umull r1, r14, r5, r5 \n\t" \ + "adds r8, r1 \n\t" \ + "adcs r9, r14 \n\t" \ + "adc r10, #0 \n\t" \ + "adds r8, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r8, r11, r4, r7 \n\t" \ + "umull r1, r14, r5, r6 \n\t" \ + "adds r8, r1 \n\t" \ + "adcs r11, r14 \n\t" \ + "adc r12, #0 \n\t" \ + "adds r8, r8 \n\t" \ + "adcs r11, r11 \n\t" \ + "adc r12, r12 \n\t" \ + "adds r8, r9 \n\t" \ + "adcs r11, r10 \n\t" \ + "adc r12, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r8, #0 \n\t" \ + "umull r1, r10, r5, r7 \n\t" \ + "adds r1, r1 \n\t" \ + "adcs r10, r10 \n\t" \ + "adc r8, #0 \n\t" \ + "adds r11, r1 \n\t" \ + "adcs r12, r10 \n\t" \ + "adc r8, #0 \n\t" \ + "umull r1, r10, r6, r6 \n\t" \ + "adds r11, r1 \n\t" \ + "adcs r12, r10 \n\t" \ + "adc r8, #0 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "mov r11, #0 \n\t" \ + "umull r1, r10, r6, r7 \n\t" \ + "adds r1, r1 \n\t" \ + "adcs r10, r10 \n\t" \ + "adc r11, #0 \n\t" \ + "adds r12, r1 \n\t" \ + "adcs r8, r10 \n\t" \ + "adc r11, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "umull r1, r10, r7, r7 \n\t" \ + "adds r8, r1 \n\t" \ + "adcs r11, r10 \n\t" \ + "stmia r0!, {r8, r11} \n\t" + +#define FAST_SQUARE_ASM_7 \ + "ldmia r1!, {r2} \n\t" \ + "add r1, 20 \n\t" \ + "ldmia r1!, {r5} \n\t" \ + "add r0, 24 \n\t" \ + "umull r8, r9, r2, r5 \n\t" \ + "stmia r0!, {r8, r9} \n\t" \ + "sub r0, 32 \n\t" \ + "sub r1, 28 \n\t" \ + \ + "ldmia r1!, {r2, r3, r4, r5, r6, r7} \n\t" \ + \ + "umull r11, r12, r2, r2 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "mov r9, #0 \n\t" \ + "umull r10, r11, r2, r3 \n\t" \ + "adds r12, r10 \n\t" \ + "adcs r8, r11, #0 \n\t" \ + "adc r9, #0 \n\t" \ + "adds r12, r10 \n\t" \ + "adcs r8, r11 \n\t" \ + "adc r9, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r2, r4 \n\t" \ + "adds r11, r11 \n\t" \ + "adcs r12, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "adds r8, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "umull r11, r12, r3, r3 \n\t" \ + "adds r8, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r8, r11, r2, r5 \n\t" \ + "mov r14, r11 \n\t" \ + "umlal r8, r11, r3, r4 \n\t" \ + "cmp r14, r11 \n\t" \ + "it hi \n\t" \ + "adchi r12, #0 \n\t" \ + "adds r8, r8 \n\t" \ + "adcs r11, r11 \n\t" \ + "adc r12, r12 \n\t" \ + "adds r8, r9 \n\t" \ + "adcs r11, r10 \n\t" \ + "adc r12, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r8, r9, r2, r6 \n\t" \ + "mov r14, r9 \n\t" \ + "umlal r8, r9, r3, r5 \n\t" \ + "cmp r14, r9 \n\t" \ + "it hi \n\t" \ + "adchi r10, #0 \n\t" \ + "adds r8, r8 \n\t" \ + "adcs r9, r9 \n\t" \ + "adc r10, r10 \n\t" \ + "mov r14, r9 \n\t" \ + "umlal r8, r9, r4, r4 \n\t" \ + "cmp r14, r9 \n\t" \ + "it hi \n\t" \ + "adchi r10, #0 \n\t" \ + "adds r8, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r8, r11, r2, r7 \n\t" \ + "mov r14, r11 \n\t" \ + "umlal r8, r11, r3, r6 \n\t" \ + "cmp r14, r11 \n\t" \ + "it hi \n\t" \ + "adchi r12, #0 \n\t" \ + "mov r14, r11 \n\t" \ + "umlal r8, r11, r4, r5 \n\t" \ + "cmp r14, r11 \n\t" \ + "it hi \n\t" \ + "adchi r12, #0 \n\t" \ + "adds r8, r8 \n\t" \ + "adcs r11, r11 \n\t" \ + "adc r12, r12 \n\t" \ + "adds r8, r9 \n\t" \ + "adcs r11, r10 \n\t" \ + "adc r12, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "ldmia r1!, {r2} \n\t" \ + "mov r10, #0 \n\t" \ + "umull r8, r9, r3, r7 \n\t" \ + "mov r14, r9 \n\t" \ + "umlal r8, r9, r4, r6 \n\t" \ + "cmp r14, r9 \n\t" \ + "it hi \n\t" \ + "adchi r10, #0 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adds r8, r14 \n\t" \ + "adcs r9, #0 \n\t" \ + "adc r10, #0 \n\t" \ + "adds r8, r8 \n\t" \ + "adcs r9, r9 \n\t" \ + "adc r10, r10 \n\t" \ + "mov r14, r9 \n\t" \ + "umlal r8, r9, r5, r5 \n\t" \ + "cmp r14, r9 \n\t" \ + "it hi \n\t" \ + "adchi r10, #0 \n\t" \ + "adds r8, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r8, r11, r3, r2 \n\t" \ + "mov r14, r11 \n\t" \ + "umlal r8, r11, r4, r7 \n\t" \ + "cmp r14, r11 \n\t" \ + "it hi \n\t" \ + "adchi r12, #0 \n\t" \ + "mov r14, r11 \n\t" \ + "umlal r8, r11, r5, r6 \n\t" \ + "cmp r14, r11 \n\t" \ + "it hi \n\t" \ + "adchi r12, #0 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adds r8, r14 \n\t" \ + "adcs r11, #0 \n\t" \ + "adc r12, #0 \n\t" \ + "adds r8, r8 \n\t" \ + "adcs r11, r11 \n\t" \ + "adc r12, r12 \n\t" \ + "adds r8, r9 \n\t" \ + "adcs r11, r10 \n\t" \ + "adc r12, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r8, r9, r4, r2 \n\t" \ + "mov r14, r9 \n\t" \ + "umlal r8, r9, r5, r7 \n\t" \ + "cmp r14, r9 \n\t" \ + "it hi \n\t" \ + "adchi r10, #0 \n\t" \ + "adds r8, r8 \n\t" \ + "adcs r9, r9 \n\t" \ + "adc r10, r10 \n\t" \ + "mov r14, r9 \n\t" \ + "umlal r8, r9, r6, r6 \n\t" \ + "cmp r14, r9 \n\t" \ + "it hi \n\t" \ + "adchi r10, #0 \n\t" \ + "adds r8, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r8, r11, r5, r2 \n\t" \ + "mov r14, r11 \n\t" \ + "umlal r8, r11, r6, r7 \n\t" \ + "cmp r14, r11 \n\t" \ + "it hi \n\t" \ + "adchi r12, #0 \n\t" \ + "adds r8, r8 \n\t" \ + "adcs r11, r11 \n\t" \ + "adc r12, r12 \n\t" \ + "adds r8, r9 \n\t" \ + "adcs r11, r10 \n\t" \ + "adc r12, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r8, #0 \n\t" \ + "umull r1, r10, r6, r2 \n\t" \ + "adds r1, r1 \n\t" \ + "adcs r10, r10 \n\t" \ + "adc r8, #0 \n\t" \ + "adds r11, r1 \n\t" \ + "adcs r12, r10 \n\t" \ + "adc r8, #0 \n\t" \ + "umull r1, r10, r7, r7 \n\t" \ + "adds r11, r1 \n\t" \ + "adcs r12, r10 \n\t" \ + "adc r8, #0 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "mov r11, #0 \n\t" \ + "umull r1, r10, r7, r2 \n\t" \ + "adds r1, r1 \n\t" \ + "adcs r10, r10 \n\t" \ + "adc r11, #0 \n\t" \ + "adds r12, r1 \n\t" \ + "adcs r8, r10 \n\t" \ + "adc r11, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "umull r1, r10, r2, r2 \n\t" \ + "adds r8, r1 \n\t" \ + "adcs r11, r10 \n\t" \ + "stmia r0!, {r8, r11} \n\t" + +#define FAST_SQUARE_ASM_8 \ + "ldmia r1!, {r2, r3} \n\t" \ + "add r1, 16 \n\t" \ + "ldmia r1!, {r5, r6} \n\t" \ + "add r0, 24 \n\t" \ + \ + "umull r8, r9, r2, r5 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "umull r12, r10, r2, r6 \n\t" \ + "adds r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "stmia r0!, {r9} \n\t" \ + \ + "umull r8, r9, r3, r6 \n\t" \ + "adds r10, r8 \n\t" \ + "adc r11, r9, #0 \n\t" \ + "stmia r0!, {r10, r11} \n\t" \ + \ + "sub r0, 40 \n\t" \ + "sub r1, 32 \n\t" \ + "ldmia r1!, {r2,r3,r4,r5,r6,r7} \n\t" \ + \ + "umull r11, r12, r2, r2 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "mov r9, #0 \n\t" \ + "umull r10, r11, r2, r3 \n\t" \ + "adds r12, r10 \n\t" \ + "adcs r8, r11, #0 \n\t" \ + "adc r9, #0 \n\t" \ + "adds r12, r10 \n\t" \ + "adcs r8, r11 \n\t" \ + "adc r9, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r2, r4 \n\t" \ + "adds r11, r11 \n\t" \ + "adcs r12, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "adds r8, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "umull r11, r12, r3, r3 \n\t" \ + "adds r8, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r8, r11, r2, r5 \n\t" \ + "mov r14, r11 \n\t" \ + "umlal r8, r11, r3, r4 \n\t" \ + "cmp r14, r11 \n\t" \ + "it hi \n\t" \ + "adchi r12, #0 \n\t" \ + "adds r8, r8 \n\t" \ + "adcs r11, r11 \n\t" \ + "adc r12, r12 \n\t" \ + "adds r8, r9 \n\t" \ + "adcs r11, r10 \n\t" \ + "adc r12, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r8, r9, r2, r6 \n\t" \ + "mov r14, r9 \n\t" \ + "umlal r8, r9, r3, r5 \n\t" \ + "cmp r14, r9 \n\t" \ + "it hi \n\t" \ + "adchi r10, #0 \n\t" \ + "adds r8, r8 \n\t" \ + "adcs r9, r9 \n\t" \ + "adc r10, r10 \n\t" \ + "mov r14, r9 \n\t" \ + "umlal r8, r9, r4, r4 \n\t" \ + "cmp r14, r9 \n\t" \ + "it hi \n\t" \ + "adchi r10, #0 \n\t" \ + "adds r8, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r8, r11, r2, r7 \n\t" \ + "mov r14, r11 \n\t" \ + "umlal r8, r11, r3, r6 \n\t" \ + "cmp r14, r11 \n\t" \ + "it hi \n\t" \ + "adchi r12, #0 \n\t" \ + "mov r14, r11 \n\t" \ + "umlal r8, r11, r4, r5 \n\t" \ + "cmp r14, r11 \n\t" \ + "it hi \n\t" \ + "adchi r12, #0 \n\t" \ + "adds r8, r8 \n\t" \ + "adcs r11, r11 \n\t" \ + "adc r12, r12 \n\t" \ + "adds r8, r9 \n\t" \ + "adcs r11, r10 \n\t" \ + "adc r12, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "ldmia r1!, {r2} \n\t" \ + "mov r10, #0 \n\t" \ + "umull r8, r9, r3, r7 \n\t" \ + "mov r14, r9 \n\t" \ + "umlal r8, r9, r4, r6 \n\t" \ + "cmp r14, r9 \n\t" \ + "it hi \n\t" \ + "adchi r10, #0 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adds r8, r14 \n\t" \ + "adcs r9, #0 \n\t" \ + "adc r10, #0 \n\t" \ + "adds r8, r8 \n\t" \ + "adcs r9, r9 \n\t" \ + "adc r10, r10 \n\t" \ + "mov r14, r9 \n\t" \ + "umlal r8, r9, r5, r5 \n\t" \ + "cmp r14, r9 \n\t" \ + "it hi \n\t" \ + "adchi r10, #0 \n\t" \ + "adds r8, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r8, r11, r3, r2 \n\t" \ + "mov r14, r11 \n\t" \ + "umlal r8, r11, r4, r7 \n\t" \ + "cmp r14, r11 \n\t" \ + "it hi \n\t" \ + "adchi r12, #0 \n\t" \ + "mov r14, r11 \n\t" \ + "umlal r8, r11, r5, r6 \n\t" \ + "cmp r14, r11 \n\t" \ + "it hi \n\t" \ + "adchi r12, #0 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adds r8, r14 \n\t" \ + "adcs r11, #0 \n\t" \ + "adc r12, #0 \n\t" \ + "adds r8, r8 \n\t" \ + "adcs r11, r11 \n\t" \ + "adc r12, r12 \n\t" \ + "adds r8, r9 \n\t" \ + "adcs r11, r10 \n\t" \ + "adc r12, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "ldmia r1!, {r3} \n\t" \ + "mov r10, #0 \n\t" \ + "umull r8, r9, r4, r2 \n\t" \ + "mov r14, r9 \n\t" \ + "umlal r8, r9, r5, r7 \n\t" \ + "cmp r14, r9 \n\t" \ + "it hi \n\t" \ + "adchi r10, #0 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adds r8, r14 \n\t" \ + "adcs r9, #0 \n\t" \ + "adc r10, #0 \n\t" \ + "adds r8, r8 \n\t" \ + "adcs r9, r9 \n\t" \ + "adc r10, r10 \n\t" \ + "mov r14, r9 \n\t" \ + "umlal r8, r9, r6, r6 \n\t" \ + "cmp r14, r9 \n\t" \ + "it hi \n\t" \ + "adchi r10, #0 \n\t" \ + "adds r8, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r8, r11, r4, r3 \n\t" \ + "mov r14, r11 \n\t" \ + "umlal r8, r11, r5, r2 \n\t" \ + "cmp r14, r11 \n\t" \ + "it hi \n\t" \ + "adchi r12, #0 \n\t" \ + "mov r14, r11 \n\t" \ + "umlal r8, r11, r6, r7 \n\t" \ + "cmp r14, r11 \n\t" \ + "it hi \n\t" \ + "adchi r12, #0 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adds r8, r14 \n\t" \ + "adcs r11, #0 \n\t" \ + "adc r12, #0 \n\t" \ + "adds r8, r8 \n\t" \ + "adcs r11, r11 \n\t" \ + "adc r12, r12 \n\t" \ + "adds r8, r9 \n\t" \ + "adcs r11, r10 \n\t" \ + "adc r12, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r8, r9, r5, r3 \n\t" \ + "mov r14, r9 \n\t" \ + "umlal r8, r9, r6, r2 \n\t" \ + "cmp r14, r9 \n\t" \ + "it hi \n\t" \ + "adchi r10, #0 \n\t" \ + "adds r8, r8 \n\t" \ + "adcs r9, r9 \n\t" \ + "adc r10, r10 \n\t" \ + "mov r14, r9 \n\t" \ + "umlal r8, r9, r7, r7 \n\t" \ + "cmp r14, r9 \n\t" \ + "it hi \n\t" \ + "adchi r10, #0 \n\t" \ + "adds r8, r11 \n\t" \ + "adcs r9, r12 \n\t" \ + "adc r10, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r8, r11, r6, r3 \n\t" \ + "mov r14, r11 \n\t" \ + "umlal r8, r11, r7, r2 \n\t" \ + "cmp r14, r11 \n\t" \ + "it hi \n\t" \ + "adchi r12, #0 \n\t" \ + "adds r8, r8 \n\t" \ + "adcs r11, r11 \n\t" \ + "adc r12, r12 \n\t" \ + "adds r8, r9 \n\t" \ + "adcs r11, r10 \n\t" \ + "adc r12, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r8, #0 \n\t" \ + "umull r1, r10, r7, r3 \n\t" \ + "adds r1, r1 \n\t" \ + "adcs r10, r10 \n\t" \ + "adc r8, #0 \n\t" \ + "adds r11, r1 \n\t" \ + "adcs r12, r10 \n\t" \ + "adc r8, #0 \n\t" \ + "umull r1, r10, r2, r2 \n\t" \ + "adds r11, r1 \n\t" \ + "adcs r12, r10 \n\t" \ + "adc r8, #0 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "mov r11, #0 \n\t" \ + "umull r1, r10, r2, r3 \n\t" \ + "adds r1, r1 \n\t" \ + "adcs r10, r10 \n\t" \ + "adc r11, #0 \n\t" \ + "adds r12, r1 \n\t" \ + "adcs r8, r10 \n\t" \ + "adc r11, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "umull r1, r10, r3, r3 \n\t" \ + "adds r8, r1 \n\t" \ + "adcs r11, r10 \n\t" \ + "stmia r0!, {r8, r11} \n\t" + +#endif /* _UECC_ASM_ARM_MULT_SQUARE_H_ */ diff --git a/asm_arm_small.inc b/asm_arm_small.inc index 2b1b0a7..8e285fa 100644 --- a/asm_arm_small.inc +++ b/asm_arm_small.inc @@ -1,3 +1,8 @@ +/* Copyright 2015, Kenneth MacKay. Licensed under the BSD 2-clause license. */ + +#ifndef _UECC_ASM_ARM_SMALL_H_ +#define _UECC_ASM_ARM_SMALL_H_ + #if (uECC_PLATFORM == uECC_arm_thumb) #define REG_RW "+l" #define REG_WRITE "=l" @@ -12,6 +17,7 @@ #define RESUME_SYNTAX ".syntax divided \n\t" #endif +#if !asm_add static uECC_word_t vli_add(uECC_word_t *result, const uECC_word_t *left, const uECC_word_t *right, @@ -41,11 +47,13 @@ static uECC_word_t vli_add(uECC_word_t *result, return carry; } #define asm_add 1 +#endif -static uint32_t vli_sub(uECC_word_t *result, - const uECC_word_t *left, - const uECC_word_t *right, - wordcount_t num_words) { +#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) { uint32_t carry = 1; /* carry = 1 initially (means don't borrow) */ uint32_t left_word; uint32_t right_word; @@ -71,7 +79,9 @@ static uint32_t vli_sub(uECC_word_t *result, return !carry; } #define asm_sub 1 +#endif +#if !asm_mult static void vli_mult(uECC_word_t *result, const uECC_word_t *left, const uECC_word_t *right, @@ -229,8 +239,10 @@ static void vli_mult(uECC_word_t *result, #endif } #define asm_mult 1 +#endif #if uECC_SQUARE_FUNC +#if !asm_square static void 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; @@ -404,4 +416,7 @@ static void vli_square(uECC_word_t *result, const uECC_word_t *left, wordcount_t #endif } #define asm_square 1 +#endif #endif /* uECC_SQUARE_FUNC */ + +#endif /* _UECC_ASM_ARM_SMALL_H_ */ diff --git a/curve-specific.inc b/curve-specific.inc index 57e528d..23a2395 100644 --- a/curve-specific.inc +++ b/curve-specific.inc @@ -1,3 +1,8 @@ +/* Copyright 2015, Kenneth MacKay. Licensed under the BSD 2-clause license. */ + +#ifndef _UECC_CURVE_SPECIFIC_H_ +#define _UECC_CURVE_SPECIFIC_H_ + #define num_bytes_secp160r1 20 #define num_bytes_secp192r1 24 #define num_bytes_secp224r1 28 @@ -46,26 +51,85 @@ #endif /* uECC_WORD_SIZE */ -static void double_jacobian_secp256k1(uECC_word_t * X1, - uECC_word_t * Y1, - uECC_word_t * Z1, - uECC_Curve curve); static void double_jacobian_default(uECC_word_t * X1, uECC_word_t * Y1, uECC_word_t * Z1, - uECC_Curve curve); + uECC_Curve curve) { + /* t1 = X, t2 = Y, t3 = Z */ + uECC_word_t t4[uECC_MAX_WORDS]; + uECC_word_t t5[uECC_MAX_WORDS]; -static void mod_sqrt_default(uECC_word_t *a, uECC_Curve curve); -static void mod_sqrt_secp224r1(uECC_word_t *a, uECC_Curve curve); + if (vli_isZero(Z1, curve->num_words)) { + return; + } -static void x_side_default(uECC_word_t *result, const uECC_word_t *x, uECC_Curve curve); -static void x_side_secp256k1(uECC_word_t *result, const uECC_word_t *x, uECC_Curve curve); + 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 */ + 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 */ + + 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); + X1[curve->num_words - 1] |= l_carry << (uECC_WORD_BITS - 1); + } else { + 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 */ + + vli_set(X1, Z1, curve->num_words); + vli_set(Z1, Y1, curve->num_words); + vli_set(Y1, t4, curve->num_words); +} + +/* Compute a = sqrt(a) (mod curve_p). */ +static void mod_sqrt_default(uECC_word_t *a, uECC_Curve curve) { + bitcount_t i; + uECC_word_t p1[uECC_MAX_WORDS] = {1}; + uECC_word_t l_result[uECC_MAX_WORDS] = {1}; + + /* 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); + } + } + vli_set(a, l_result, curve->num_words); +} + +/* Computes result = x^3 + ax + b. result must not overlap x. */ +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 */ +} + +#if uECC_SUPPORTS_secp160r1 + +#if (uECC_OPTIMIZATION_LEVEL > 0) static void vli_mmod_fast_secp160r1(uECC_word_t *result, uECC_word_t *product); -static void vli_mmod_fast_secp192r1(uECC_word_t *result, uECC_word_t *product); -static void vli_mmod_fast_secp224r1(uECC_word_t *result, uECC_word_t *product); -static void vli_mmod_fast_secp256r1(uECC_word_t *result, uECC_word_t *product); -static void vli_mmod_fast_secp256k1(uECC_word_t *result, uECC_word_t *product); +#endif static const struct uECC_Curve_t curve_secp160r1 = { num_words_secp160r1, @@ -90,9 +154,126 @@ static const struct uECC_Curve_t curve_secp160r1 = { &double_jacobian_default, &mod_sqrt_default, &x_side_default, +#if (uECC_OPTIMIZATION_LEVEL > 0) &vli_mmod_fast_secp160r1 +#endif }; +uECC_Curve uECC_secp160r1(void) { return &curve_secp160r1; } + +#if (uECC_OPTIMIZATION_LEVEL > 0) +/* Computes result = product % curve_p + see http://www.isys.uni-klu.ac.at/PDF/2001-0126-MT.pdf page 354 + + Note that this only works if log2(omega) < log2(p) / 2 */ +static void omega_mult_secp160r1(uECC_word_t *result, const uECC_word_t *right); +#if uECC_WORD_SIZE == 8 +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); + + 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); + 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 */ + + while (vli_cmp(result, curve_secp160r1.p, num_words_secp160r1) > 0) { + vli_sub(result, result, curve_secp160r1.p, num_words_secp160r1); + } +} + +static void omega_mult_secp160r1(uint64_t *result, const uint64_t *right) { + uint32_t carry; + unsigned i; + + /* Multiply by (2^31 + 1). */ + carry = 0; + for (i = 0; i < num_words_secp160r1; ++i) { + uint64_t tmp = (right[i] >> 32) | (right[i + 1] << 32); + result[i] = (tmp << 31) + tmp + carry; + carry = (tmp >> 33) + (result[i] < tmp || (carry && result[i] == tmp)); + } + result[i] = carry; +} +#else +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); + + 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); + omega_mult_secp160r1(product, tmp + num_words_secp160r1); /* Rq*c */ + carry += 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); + } + if (vli_cmp(result, curve_secp160r1.p, num_words_secp160r1) > 0) { + vli_sub(result, result, curve_secp160r1.p, num_words_secp160r1); + } +} +#endif + +#if uECC_WORD_SIZE == 1 +static void omega_mult_secp160r1(uint8_t *result, const uint8_t *right) { + uint8_t carry; + 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 */ + result[3] = right[0] << 7; /* get last bit from shift */ + + carry = 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; + carry = sum >> 8; + } +} +#elif uECC_WORD_SIZE == 4 +static void omega_mult_secp160r1(uint32_t *result, const uint32_t *right) { + uint32_t carry; + 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 */ + result[0] = right[0] << 31; /* get last bit from shift */ + + carry = 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; + carry = sum >> 32; + } +} +#endif /* uECC_WORD_SIZE */ +#endif /* (uECC_OPTIMIZATION_LEVEL > 0) */ + +#endif /* uECC_SUPPORTS_secp160r1 */ + +#if uECC_SUPPORTS_secp192r1 + +#if (uECC_OPTIMIZATION_LEVEL > 0) +static void vli_mmod_fast_secp192r1(uECC_word_t *result, uECC_word_t *product); +#endif + static const struct uECC_Curve_t curve_secp192r1 = { num_words_secp192r1, num_words_secp192r1, @@ -116,9 +297,109 @@ static const struct uECC_Curve_t curve_secp192r1 = { &double_jacobian_default, &mod_sqrt_default, &x_side_default, +#if (uECC_OPTIMIZATION_LEVEL > 0) &vli_mmod_fast_secp192r1 +#endif }; +uECC_Curve uECC_secp192r1(void) { return &curve_secp192r1; } + +#if (uECC_OPTIMIZATION_LEVEL > 0) +/* Computes result = product % curve_p. + See algorithm 5 and 6 from http://www.isys.uni-klu.ac.at/PDF/2001-0126-MT.pdf */ +#if uECC_WORD_SIZE == 1 +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); + + vli_set(tmp, &product[24], num_words_secp192r1); + carry = 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); + + tmp[0] = tmp[8] = product[40]; + tmp[1] = tmp[9] = product[41]; + tmp[2] = tmp[10] = product[42]; + tmp[3] = tmp[11] = product[43]; + tmp[4] = tmp[12] = product[44]; + tmp[5] = tmp[13] = product[45]; + 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); + + while (carry || vli_cmp(curve_secp192r1.p, result, num_words_secp192r1) != 1) { + carry -= vli_sub(result, result, curve_secp192r1.p, num_words_secp192r1); + } +} +#elif uECC_WORD_SIZE == 4 +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); + + vli_set(tmp, &product[6], num_words_secp192r1); + carry = 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); + + 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); + + while (carry || vli_cmp(curve_secp192r1.p, result, num_words_secp192r1) != 1) { + carry -= vli_sub(result, result, curve_secp192r1.p, num_words_secp192r1); + } +} +#else +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); + + vli_set(tmp, &product[3], num_words_secp192r1); + carry = 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); + + tmp[0] = tmp[1] = product[5]; + tmp[2] = 0; + carry += 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); + } +} +#endif /* uECC_WORD_SIZE */ +#endif /* (uECC_OPTIMIZATION_LEVEL > 0) */ + +#endif /* uECC_SUPPORTS_secp192r1 */ + +#if uECC_SUPPORTS_secp224r1 + +static void mod_sqrt_secp224r1(uECC_word_t *a, uECC_Curve curve); +#if (uECC_OPTIMIZATION_LEVEL > 0) +static void vli_mmod_fast_secp224r1(uECC_word_t *result, uECC_word_t *product); +#endif + static const struct uECC_Curve_t curve_secp224r1 = { num_words_secp224r1, num_words_secp224r1, @@ -147,179 +428,13 @@ static const struct uECC_Curve_t curve_secp224r1 = { &double_jacobian_default, &mod_sqrt_secp224r1, &x_side_default, +#if (uECC_OPTIMIZATION_LEVEL > 0) &vli_mmod_fast_secp224r1 +#endif }; -static const struct uECC_Curve_t curve_secp256r1 = { - num_words_secp256r1, - num_words_secp256r1, - num_bytes_secp256r1, - { BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF), - BYTES_TO_WORDS_8(FF, FF, FF, FF, 00, 00, 00, 00), - BYTES_TO_WORDS_8(00, 00, 00, 00, 00, 00, 00, 00), - BYTES_TO_WORDS_8(01, 00, 00, 00, FF, FF, FF, FF) }, - { BYTES_TO_WORDS_8(51, 25, 63, FC, C2, CA, B9, F3), - BYTES_TO_WORDS_8(84, 9E, 17, A7, AD, FA, E6, BC), - BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF), - BYTES_TO_WORDS_8(00, 00, 00, 00, FF, FF, FF, FF) }, - { BYTES_TO_WORDS_8(96, C2, 98, D8, 45, 39, A1, F4), - BYTES_TO_WORDS_8(A0, 33, EB, 2D, 81, 7D, 03, 77), - BYTES_TO_WORDS_8(F2, 40, A4, 63, E5, E6, BC, F8), - BYTES_TO_WORDS_8(47, 42, 2C, E1, F2, D1, 17, 6B), - - BYTES_TO_WORDS_8(F5, 51, BF, 37, 68, 40, B6, CB), - BYTES_TO_WORDS_8(CE, 5E, 31, 6B, 57, 33, CE, 2B), - BYTES_TO_WORDS_8(16, 9E, 0F, 7C, 4A, EB, E7, 8E), - BYTES_TO_WORDS_8(9B, 7F, 1A, FE, E2, 42, E3, 4F) }, - { BYTES_TO_WORDS_8(4B, 60, D2, 27, 3E, 3C, CE, 3B), - BYTES_TO_WORDS_8(F6, B0, 53, CC, B0, 06, 1D, 65), - BYTES_TO_WORDS_8(BC, 86, 98, 76, 55, BD, EB, B3), - BYTES_TO_WORDS_8(E7, 93, 3A, AA, D8, 35, C6, 5A) }, - &double_jacobian_default, - &mod_sqrt_default, - &x_side_default, - &vli_mmod_fast_secp256r1 -}; - -static const struct uECC_Curve_t curve_secp256k1 = { - num_words_secp256k1, - num_words_secp256k1, - num_bytes_secp256k1, - { BYTES_TO_WORDS_8(2F, FC, FF, FF, FE, FF, FF, FF), - BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF), - BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF), - BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF) }, - { BYTES_TO_WORDS_8(41, 41, 36, D0, 8C, 5E, D2, BF), - BYTES_TO_WORDS_8(3B, A0, 48, AF, E6, DC, AE, BA), - BYTES_TO_WORDS_8(FE, FF, FF, FF, FF, FF, FF, FF), - BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF) }, - { BYTES_TO_WORDS_8(98, 17, F8, 16, 5B, 81, F2, 59), - BYTES_TO_WORDS_8(D9, 28, CE, 2D, DB, FC, 9B, 02), - BYTES_TO_WORDS_8(07, 0B, 87, CE, 95, 62, A0, 55), - BYTES_TO_WORDS_8(AC, BB, DC, F9, 7E, 66, BE, 79), - - BYTES_TO_WORDS_8(B8, D4, 10, FB, 8F, D0, 47, 9C), - BYTES_TO_WORDS_8(19, 54, 85, A6, 48, B4, 17, FD), - BYTES_TO_WORDS_8(A8, 08, 11, 0E, FC, FB, A4, 5D), - BYTES_TO_WORDS_8(65, C4, A3, 26, 77, DA, 3A, 48) }, - { BYTES_TO_WORDS_8(07, 00, 00, 00, 00, 00, 00, 00), - BYTES_TO_WORDS_8(00, 00, 00, 00, 00, 00, 00, 00), - BYTES_TO_WORDS_8(00, 00, 00, 00, 00, 00, 00, 00), - BYTES_TO_WORDS_8(00, 00, 00, 00, 00, 00, 00, 00) }, - &double_jacobian_secp256k1, - &mod_sqrt_default, - &x_side_secp256k1, - &vli_mmod_fast_secp256k1 -}; - -uECC_Curve uECC_secp160r1(void) { return &curve_secp160r1; } -uECC_Curve uECC_secp192r1(void) { return &curve_secp192r1; } uECC_Curve uECC_secp224r1(void) { return &curve_secp224r1; } -uECC_Curve uECC_secp256r1(void) { return &curve_secp256r1; } -uECC_Curve uECC_secp256k1(void) { return &curve_secp256k1; } -/* Double in place */ -static void double_jacobian_secp256k1(uECC_word_t * X1, - uECC_word_t * Y1, - uECC_word_t * Z1, - uECC_Curve curve) { - /* t1 = X, t2 = Y, t3 = Z */ - uECC_word_t t4[num_words_secp256k1]; - uECC_word_t t5[num_words_secp256k1]; - - if (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 */ - - 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); - Y1[num_words_secp256k1 - 1] |= carry << (uECC_WORD_BITS - 1); - } else { - 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 */ - - 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 */ -} - -static void double_jacobian_default(uECC_word_t * X1, - uECC_word_t * Y1, - uECC_word_t * Z1, - uECC_Curve curve) { - /* t1 = X, t2 = Y, t3 = Z */ - uECC_word_t t4[uECC_MAX_WORDS]; - uECC_word_t t5[uECC_MAX_WORDS]; - - if (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 */ - - 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 */ - - 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); - X1[curve->num_words - 1] |= l_carry << (uECC_WORD_BITS - 1); - } else { - 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 */ - - vli_set(X1, Z1, curve->num_words); - vli_set(Z1, Y1, curve->num_words); - vli_set(Y1, t4, curve->num_words); -} - -/* Compute a = sqrt(a) (mod curve_p). */ -static void mod_sqrt_default(uECC_word_t *a, uECC_Curve curve) { - bitcount_t i; - uECC_word_t p1[uECC_MAX_WORDS] = {1}; - uECC_word_t l_result[uECC_MAX_WORDS] = {1}; - - /* 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); - } - } - vli_set(a, l_result, curve->num_words); -} /* Routine 3.2.4 RS; from http://www.nsa.gov/ia/_files/nist-routines.pdf */ static void mod_sqrt_secp224r1_rs(uECC_word_t *d1, @@ -437,213 +552,11 @@ static void mod_sqrt_secp224r1(uECC_word_t *a, uECC_Curve curve) { vli_modMult_fast(a, d0, f1, &curve_secp224r1); /* a <-- d0 / e0 */ } -/* Computes result = x^3 + ax + b. result must not overlap x. */ -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 */ -} - -/* 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 */ -} - -/* Computes result = product % curve_p - see http://www.isys.uni-klu.ac.at/PDF/2001-0126-MT.pdf page 354 - - Note that this only works if log2(omega) < log2(p) / 2 */ -static void omega_mult_secp160r1(uECC_word_t *result, const uECC_word_t *right); -#if uECC_WORD_SIZE == 8 -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, 2 * 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); - 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 */ - - while (vli_cmp(result, curve_secp160r1.p, num_words_secp160r1) > 0) { - vli_sub(result, result, curve_secp160r1.p, num_words_secp160r1); - } -} - -static void omega_mult_secp160r1(uint64_t *result, const uint64_t *right) { - uint32_t carry; - unsigned i; - - /* Multiply by (2^31 + 1). */ - carry = 0; - for (i = 0; i < num_words_secp160r1; ++i) { - uint64_t tmp = (right[i] >> 32) | (right[i + 1] << 32); - result[i] = (tmp << 31) + tmp + carry; - carry = (tmp >> 33) + (result[i] < tmp || (carry && result[i] == tmp)); - } - result[i] = carry; -} -#else -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, 2 * 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); - omega_mult_secp160r1(product, tmp + num_words_secp160r1); /* Rq*c */ - carry += 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); - } - if (vli_cmp(result, curve_secp160r1.p, num_words_secp160r1) > 0) { - vli_sub(result, result, curve_secp160r1.p, num_words_secp160r1); - } -} -#endif - -#if uECC_WORD_SIZE == 1 -static void omega_mult_secp160r1(uint8_t *result, const uint8_t *right) { - uint8_t carry; - 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 */ - result[3] = right[0] << 7; /* get last bit from shift */ - - carry = 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; - carry = sum >> 8; - } -} -#elif uECC_WORD_SIZE == 4 -static void omega_mult_secp160r1(uint32_t *result, const uint32_t *right) { - uint32_t carry; - 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 */ - result[0] = right[0] << 31; /* get last bit from shift */ - - carry = 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; - carry = sum >> 32; - } -} -#endif /* uECC_WORD_SIZE */ - -/* Computes result = product % curve_p. - See algorithm 5 and 6 from http://www.isys.uni-klu.ac.at/PDF/2001-0126-MT.pdf */ -#if uECC_WORD_SIZE == 1 -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); - - vli_set(tmp, &product[24], num_words_secp192r1); - carry = 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); - - tmp[0] = tmp[8] = product[40]; - tmp[1] = tmp[9] = product[41]; - tmp[2] = tmp[10] = product[42]; - tmp[3] = tmp[11] = product[43]; - tmp[4] = tmp[12] = product[44]; - tmp[5] = tmp[13] = product[45]; - 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); - - while (carry || vli_cmp(curve_secp192r1.p, result, num_words_secp192r1) != 1) { - carry -= vli_sub(result, result, curve_secp192r1.p, num_words_secp192r1); - } -} -#elif uECC_WORD_SIZE == 4 -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); - - vli_set(tmp, &product[6], num_words_secp192r1); - carry = 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); - - 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); - - while (carry || vli_cmp(curve_secp192r1.p, result, num_words_secp192r1) != 1) { - carry -= vli_sub(result, result, curve_secp192r1.p, num_words_secp192r1); - } -} -#else -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); - - vli_set(tmp, &product[3], num_words_secp192r1); - carry = 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); - - tmp[0] = tmp[1] = product[5]; - tmp[2] = 0; - carry += 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); - } -} -#endif /* uECC_WORD_SIZE */ - +#if (uECC_OPTIMIZATION_LEVEL > 0) /* Computes result = product % curve_p from http://www.nsa.gov/ia/_files/nist-routines.pdf */ #if uECC_WORD_SIZE == 1 -void vli_mmod_fast_secp224r1(uint8_t *result, uint8_t *product) { +static void vli_mmod_fast_secp224r1(uint8_t *result, uint8_t *product) { uint8_t tmp[num_words_secp224r1]; int8_t carry; @@ -698,7 +611,7 @@ void vli_mmod_fast_secp224r1(uint8_t *result, uint8_t *product) { } } #elif uECC_WORD_SIZE == 4 -void vli_mmod_fast_secp224r1(uint32_t *result, uint32_t *product) +static void vli_mmod_fast_secp224r1(uint32_t *result, uint32_t *product) { uint32_t tmp[num_words_secp224r1]; int carry; @@ -749,7 +662,7 @@ void vli_mmod_fast_secp224r1(uint32_t *result, uint32_t *product) } } #else -void vli_mmod_fast_secp224r1(uint64_t *result, uint64_t *product) +static void vli_mmod_fast_secp224r1(uint64_t *result, uint64_t *product) { uint64_t tmp[num_words_secp224r1]; int carry = 0; @@ -795,7 +708,53 @@ void vli_mmod_fast_secp224r1(uint64_t *result, uint64_t *product) } } #endif /* uECC_WORD_SIZE */ +#endif /* (uECC_OPTIMIZATION_LEVEL > 0) */ +#endif /* uECC_SUPPORTS_secp224r1 */ + +#if uECC_SUPPORTS_secp256r1 + +#if (uECC_OPTIMIZATION_LEVEL > 0) +static void vli_mmod_fast_secp256r1(uECC_word_t *result, uECC_word_t *product); +#endif + +static const struct uECC_Curve_t curve_secp256r1 = { + num_words_secp256r1, + num_words_secp256r1, + num_bytes_secp256r1, + { BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF), + BYTES_TO_WORDS_8(FF, FF, FF, FF, 00, 00, 00, 00), + BYTES_TO_WORDS_8(00, 00, 00, 00, 00, 00, 00, 00), + BYTES_TO_WORDS_8(01, 00, 00, 00, FF, FF, FF, FF) }, + { BYTES_TO_WORDS_8(51, 25, 63, FC, C2, CA, B9, F3), + BYTES_TO_WORDS_8(84, 9E, 17, A7, AD, FA, E6, BC), + BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF), + BYTES_TO_WORDS_8(00, 00, 00, 00, FF, FF, FF, FF) }, + { BYTES_TO_WORDS_8(96, C2, 98, D8, 45, 39, A1, F4), + BYTES_TO_WORDS_8(A0, 33, EB, 2D, 81, 7D, 03, 77), + BYTES_TO_WORDS_8(F2, 40, A4, 63, E5, E6, BC, F8), + BYTES_TO_WORDS_8(47, 42, 2C, E1, F2, D1, 17, 6B), + + BYTES_TO_WORDS_8(F5, 51, BF, 37, 68, 40, B6, CB), + BYTES_TO_WORDS_8(CE, 5E, 31, 6B, 57, 33, CE, 2B), + BYTES_TO_WORDS_8(16, 9E, 0F, 7C, 4A, EB, E7, 8E), + BYTES_TO_WORDS_8(9B, 7F, 1A, FE, E2, 42, E3, 4F) }, + { BYTES_TO_WORDS_8(4B, 60, D2, 27, 3E, 3C, CE, 3B), + BYTES_TO_WORDS_8(F6, B0, 53, CC, B0, 06, 1D, 65), + BYTES_TO_WORDS_8(BC, 86, 98, 76, 55, BD, EB, B3), + BYTES_TO_WORDS_8(E7, 93, 3A, AA, D8, 35, C6, 5A) }, + &double_jacobian_default, + &mod_sqrt_default, + &x_side_default, +#if (uECC_OPTIMIZATION_LEVEL > 0) + &vli_mmod_fast_secp256r1 +#endif +}; + +uECC_Curve uECC_secp256r1(void) { return &curve_secp256r1; } + + +#if (uECC_OPTIMIZATION_LEVEL > 0) /* Computes result = product % curve_p from http://www.nsa.gov/ia/_files/nist-routines.pdf */ #if uECC_WORD_SIZE == 1 @@ -1077,13 +1036,111 @@ static void vli_mmod_fast_secp256r1(uint64_t *result, uint64_t *product) { } } #endif /* uECC_WORD_SIZE */ +#endif /* (uECC_OPTIMIZATION_LEVEL > 0) */ +#endif /* uECC_SUPPORTS_secp256r1 */ + +#if uECC_SUPPORTS_secp256k1 + +static void double_jacobian_secp256k1(uECC_word_t * X1, + uECC_word_t * Y1, + uECC_word_t * Z1, + uECC_Curve curve); +static void x_side_secp256k1(uECC_word_t *result, const uECC_word_t *x, uECC_Curve curve); +#if (uECC_OPTIMIZATION_LEVEL > 0) +static void vli_mmod_fast_secp256k1(uECC_word_t *result, uECC_word_t *product); +#endif + +static const struct uECC_Curve_t curve_secp256k1 = { + num_words_secp256k1, + num_words_secp256k1, + num_bytes_secp256k1, + { BYTES_TO_WORDS_8(2F, FC, FF, FF, FE, FF, FF, FF), + BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF), + BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF), + BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF) }, + { BYTES_TO_WORDS_8(41, 41, 36, D0, 8C, 5E, D2, BF), + BYTES_TO_WORDS_8(3B, A0, 48, AF, E6, DC, AE, BA), + BYTES_TO_WORDS_8(FE, FF, FF, FF, FF, FF, FF, FF), + BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF) }, + { BYTES_TO_WORDS_8(98, 17, F8, 16, 5B, 81, F2, 59), + BYTES_TO_WORDS_8(D9, 28, CE, 2D, DB, FC, 9B, 02), + BYTES_TO_WORDS_8(07, 0B, 87, CE, 95, 62, A0, 55), + BYTES_TO_WORDS_8(AC, BB, DC, F9, 7E, 66, BE, 79), + + BYTES_TO_WORDS_8(B8, D4, 10, FB, 8F, D0, 47, 9C), + BYTES_TO_WORDS_8(19, 54, 85, A6, 48, B4, 17, FD), + BYTES_TO_WORDS_8(A8, 08, 11, 0E, FC, FB, A4, 5D), + BYTES_TO_WORDS_8(65, C4, A3, 26, 77, DA, 3A, 48) }, + { BYTES_TO_WORDS_8(07, 00, 00, 00, 00, 00, 00, 00), + BYTES_TO_WORDS_8(00, 00, 00, 00, 00, 00, 00, 00), + BYTES_TO_WORDS_8(00, 00, 00, 00, 00, 00, 00, 00), + BYTES_TO_WORDS_8(00, 00, 00, 00, 00, 00, 00, 00) }, + &double_jacobian_secp256k1, + &mod_sqrt_default, + &x_side_secp256k1, +#if (uECC_OPTIMIZATION_LEVEL > 0) + &vli_mmod_fast_secp256k1 +#endif +}; + +uECC_Curve uECC_secp256k1(void) { return &curve_secp256k1; } + + +/* Double in place */ +static void double_jacobian_secp256k1(uECC_word_t * X1, + uECC_word_t * Y1, + uECC_word_t * Z1, + uECC_Curve curve) { + /* t1 = X, t2 = Y, t3 = Z */ + uECC_word_t t4[num_words_secp256k1]; + uECC_word_t t5[num_words_secp256k1]; + + if (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 */ + + 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); + Y1[num_words_secp256k1 - 1] |= carry << (uECC_WORD_BITS - 1); + } else { + 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 */ + + 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 */ +} + +/* 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 */ +} + +#if (uECC_OPTIMIZATION_LEVEL > 0) static void omega_mult_secp256k1(uECC_word_t *result, const uECC_word_t *right); 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, 2 * num_words_secp256k1); + vli_clear(tmp, num_words_secp256k1); + vli_clear(tmp + num_words_secp256k1, num_words_secp256k1); omega_mult_secp256k1(tmp, product + num_words_secp256k1); /* (Rq, q) = q * c */ @@ -1163,3 +1220,8 @@ static void omega_mult_secp256k1(uint64_t * result, const uint64_t * right) { result[num_words_secp256k1] = r0; } #endif /* uECC_WORD_SIZE */ +#endif /* (uECC_OPTIMIZATION_LEVEL > 0) */ + +#endif /* uECC_SUPPORTS_secp256k1 */ + +#endif /* _UECC_CURVE_SPECIFIC_H_ */ diff --git a/platform-specific.inc b/platform-specific.inc index bf15ce2..207ac8b 100644 --- a/platform-specific.inc +++ b/platform-specific.inc @@ -1,3 +1,8 @@ +/* Copyright 2015, Kenneth MacKay. Licensed under the BSD 2-clause license. */ + +#ifndef _UECC_PLATFORM_SPECIFIC_H_ +#define _UECC_PLATFORM_SPECIFIC_H_ + #ifndef uECC_PLATFORM #if __AVR__ #define uECC_PLATFORM uECC_avr @@ -32,29 +37,16 @@ #error "Unsupported value for uECC_WORD_SIZE" #endif -/* Optimization options... */ -#define uECC_asm_none 0 -#define uECC_asm_small 1 -#define uECC_asm_fast 2 -#ifndef uECC_ASM - #define uECC_ASM uECC_asm_small -#endif - -#ifndef uECC_SQUARE_FUNC - #define uECC_SQUARE_FUNC 0 -#endif -/* --- end --- */ - -#if (uECC_ASM && (uECC_PLATFORM == uECC_avr) && (uECC_WORD_SIZE != 1)) - #pragma message ("uECC_WORD_SIZE must be 1 when using AVR asm") +#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_ASM && \ - (uECC_PLATFORM == uECC_arm || uECC_PLATFORM == uECC_arm_thumb) && \ +#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 when using ARM asm") + #pragma message ("uECC_WORD_SIZE must be 4 for ARM") #undef uECC_WORD_SIZE #define uECC_WORD_SIZE 4 #endif @@ -172,15 +164,6 @@ static int default_RNG(uint8_t *dest, unsigned size) { return 0; } -#endif +#endif /* platform */ -// #ifdef __GNUC__ /* Only support GCC inline asm for now */ -// #if (uECC_ASM && (uECC_PLATFORM == uECC_avr)) -// #include "asm_avr.inc" -// #endif -// -// #if (uECC_ASM && (uECC_PLATFORM == uECC_arm || uECC_PLATFORM == uECC_arm_thumb || \ -// uECC_PLATFORM == uECC_arm_thumb2)) -// #include "asm_arm.inc" -// #endif -// #endif +#endif /* _UECC_PLATFORM_SPECIFIC_H_ */ diff --git a/uECC.c b/uECC.c index 2820f6c..4c32e54 100644 --- a/uECC.c +++ b/uECC.c @@ -4,14 +4,30 @@ #define MAX_TRIES 64 +#if uECC_SUPPORTS_secp160r1 + #define uECC_MAX_BYTES 21 /* Due to the size of curve_n. */ +#endif +#if uECC_SUPPORTS_secp192r1 + #undef uECC_MAX_BYTES + #define uECC_MAX_BYTES 24 +#endif +#if uECC_SUPPORTS_secp224r1 + #undef uECC_MAX_BYTES + #define uECC_MAX_BYTES 28 +#endif +#if (uECC_SUPPORTS_secp256r1 || uECC_SUPPORTS_secp256k1) + #undef uECC_MAX_BYTES + #define uECC_MAX_BYTES 32 +#endif + #include "platform-specific.inc" #if (uECC_WORD_SIZE == 1) - #define uECC_MAX_WORDS 32 + #define uECC_MAX_WORDS uECC_MAX_BYTES #elif (uECC_WORD_SIZE == 4) - #define uECC_MAX_WORDS 8 + #define uECC_MAX_WORDS ((uECC_MAX_BYTES + 3) / 4) #elif (uECC_WORD_SIZE == 8) - #define uECC_MAX_WORDS 4 + #define uECC_MAX_WORDS ((uECC_MAX_BYTES + 7) / 8) #endif /* uECC_WORD_SIZE */ struct uECC_Curve_t { @@ -28,14 +44,24 @@ struct uECC_Curve_t { uECC_Curve curve); void (*mod_sqrt)(uECC_word_t *a, uECC_Curve curve); void (*x_side)(uECC_word_t *result, const uECC_word_t *x, uECC_Curve curve); +#if (uECC_OPTIMIZATION_LEVEL > 0) void (*mmod_fast)(uECC_word_t *result, uECC_word_t *product); +#endif }; -#if (uECC_ASM == uECC_asm_small) - #if (uECC_PLATFORM == uECC_arm || uECC_PLATFORM == uECC_arm_thumb || \ - uECC_PLATFORM == uECC_arm_thumb2) - #include "asm_arm_small.inc" +#if (uECC_OPTIMIZATION_LEVEL > 0) && (uECC_OPTIMIZATION_LEVEL % 2 == 0) + #define uECC_SQUARE_FUNC 1 +#else + #define uECC_SQUARE_FUNC 0 +#endif + +#if (uECC_PLATFORM == uECC_arm || uECC_PLATFORM == uECC_arm_thumb || \ + uECC_PLATFORM == uECC_arm_thumb2) + #if (uECC_OPTIMIZATION_LEVEL > 2) + #include "asm_arm_mult_square.inc" + #include "asm_arm_fast.inc" #endif + #include "asm_arm_small.inc" #endif static uECC_RNG_Function g_rng_function = &default_RNG; @@ -190,7 +216,7 @@ static void muladd(uECC_word_t a, i2 += (i0 >> 32); i2 += i1; - if (i2 < i1) { // overflow + if (i2 < i1) { /* overflow */ i3 += 0x100000000ull; } @@ -266,7 +292,7 @@ static void mul2add(uECC_word_t a, i2 += (i0 >> 32); i2 += i1; if (i2 < i1) - { // overflow + { /* overflow */ i3 += 0x100000000ull; } @@ -365,7 +391,7 @@ static void vli_mmod(uECC_word_t *result, uECC_word_t *v[2] = {tmp, product}; uECC_word_t index; - // Shift mod so its highest set bit is at the maximum position. + /* 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); wordcount_t word_shift = shift / uECC_WORD_BITS; wordcount_t bit_shift = shift % uECC_WORD_BITS; @@ -381,9 +407,19 @@ static void vli_mmod(uECC_word_t *result, } for (index = 1; shift >= 0; --shift) { - uECC_word_t borrow = vli_sub(v[1 - index], v[index], mod_multiple, num_words * 2); + uECC_word_t borrow = 0; + wordcount_t i; + for (i = 0; i < num_words * 2; ++i) { + uECC_word_t diff = v[index][i] - mod_multiple[i] - borrow; + if (diff != v[index][i]) { + borrow = (diff > v[index][i]); + } + v[1 - index][i] = diff; + } index = !(index ^ borrow); /* Swap the index if there was no borrow */ - vli_rshift1(mod_multiple, num_words * 2); + 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); } vli_set(result, v[index], num_words); } @@ -399,6 +435,8 @@ static void vli_modMult(uECC_word_t *result, vli_mmod(result, product, mod, 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, @@ -408,6 +446,13 @@ static void vli_modMult_fast(uECC_word_t *result, curve->mmod_fast(result, product); } +#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. */ @@ -420,6 +465,8 @@ static void vli_modSquare(uECC_word_t *result, vli_mmod(result, product, mod, num_words); } +#if (uECC_OPTIMIZATION_LEVEL > 0) + static void vli_modSquare_fast(uECC_word_t *result, const uECC_word_t *left, uECC_Curve curve) { @@ -428,6 +475,13 @@ static void vli_modSquare_fast(uECC_word_t *result, curve->mmod_fast(result, product); } +#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) \ @@ -508,7 +562,8 @@ static void vli_modInv(uECC_word_t *result, /* Returns 1 if 'point' is the point at infinity, 0 otherwise. */ static cmpresult_t EccPoint_isZero(const uECC_word_t *point, uECC_Curve curve) { - return vli_isZero(point, curve->num_words * 2); + return vli_isZero(point, curve->num_words) && + vli_isZero(point + curve->num_words, curve->num_words); } /* Point multiplication algorithm using Montgomery's ladder with co-Z coordinates. @@ -695,8 +750,8 @@ static uECC_word_t EccPoint_compute_public_key(uECC_word_t *result, return 0; } - // Regularize the bitcount for the private key so that attackers cannot use a side channel - // attack to learn the number of leading zeros. + /* Regularize the bitcount for the private key so that attackers cannot use a side channel + attack to learn the number of leading zeros. */ carry = regularize_k(private, tmp1, tmp2, curve); EccPoint_mult(result, curve->G, p2[!carry], 0, @@ -822,12 +877,12 @@ int uECC_shared_secret(const uint8_t *public_key, vli_bytesToNative(public, public_key, curve); 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. + /* Regularize the bitcount for the private key so that attackers cannot use a side channel + attack to learn the number of leading zeros. */ carry = regularize_k(private, private, tmp, curve); - // If an RNG function was specified, try to get a random initial Z value to improve - // protection against side-channel attacks. + /* If an RNG function was specified, try to get a random initial Z value to improve + protection against side-channel attacks. */ if (g_rng_function != &default_RNG) { for (tries = 0; tries < MAX_TRIES; ++tries) { if (!generate_random_int(p2[carry], curve->num_words, curve->num_bytes * 8)) { @@ -880,12 +935,12 @@ int uECC_valid_public_key(const uint8_t *public_key, uECC_Curve curve) { vli_bytesToNative(public, public_key, curve); vli_bytesToNative(public + curve->num_words, public_key + curve->num_bytes, curve); - // The point at infinity is invalid. + /* The point at infinity is invalid. */ if (EccPoint_isZero(public, curve)) { return 0; } - - // x and y must be smaller than p. + + /* x and y must be smaller than p. */ if (vli_cmp(curve->p, public, curve->num_words) != 1 || vli_cmp(curve->p, public + curve->num_words, curve->num_words) != 1) { return 0; @@ -1065,8 +1120,8 @@ int uECC_sign_deterministic(const uint8_t *private_key, V[i] = 0x01; K[i] = 0; } - - // K = HMAC_K(V || 0x00 || int2octets(x) || h(m)) + + /* K = HMAC_K(V || 0x00 || int2octets(x) || h(m)) */ HMAC_init(hash_context, K); V[hash_context->result_size] = 0x00; HMAC_update(hash_context, V, hash_context->result_size + 1); @@ -1075,8 +1130,8 @@ int uECC_sign_deterministic(const uint8_t *private_key, HMAC_finish(hash_context, K, K); update_V(hash_context, K, V); - - // K = HMAC_K(V || 0x01 || int2octets(x) || h(m)) + + /* K = HMAC_K(V || 0x01 || int2octets(x) || h(m)) */ HMAC_init(hash_context, K); V[hash_context->result_size] = 0x01; HMAC_update(hash_context, V, hash_context->result_size + 1); @@ -1106,7 +1161,7 @@ int uECC_sign_deterministic(const uint8_t *private_key, return 1; } - // K = HMAC_K(V || 0x00) + /* K = HMAC_K(V || 0x00) */ HMAC_init(hash_context, K); V[hash_context->result_size] = 0x00; HMAC_update(hash_context, V, hash_context->result_size + 1); diff --git a/uECC.h b/uECC.h index 6e416c3..0c4b092 100644 --- a/uECC.h +++ b/uECC.h @@ -1,7 +1,7 @@ /* Copyright 2014, Kenneth MacKay. Licensed under the BSD 2-clause license. */ -#ifndef _MICRO_ECC_H_ -#define _MICRO_ECC_H_ +#ifndef _UECC_H_ +#define _UECC_H_ #include @@ -17,11 +17,34 @@ Possible values for uECC_PLATFORM are defined below: */ #define uECC_arm64 6 #define uECC_avr 7 - /* If desired, you can define uECC_WORD_SIZE as appropriate for your platform (1, 4, or 8 bytes). If uECC_WORD_SIZE is not explicitly defined then it will be automatically set based on your platform. */ +/* Optimization level; trade speed for code size. + Larger values produce code that is faster but larger. + Currently supported values are 0 - 4; 0 is unusably slow for most applications. */ +#ifndef uECC_OPTIMIZATION_LEVEL + #define uECC_OPTIMIZATION_LEVEL 1 +#endif + +/* Curve support selection. Set to 0 to remove that curve. */ +#ifndef uECC_SUPPORTS_secp160r1 + #define uECC_SUPPORTS_secp160r1 1 +#endif +#ifndef uECC_SUPPORTS_secp192r1 + #define uECC_SUPPORTS_secp192r1 1 +#endif +#ifndef uECC_SUPPORTS_secp224r1 + #define uECC_SUPPORTS_secp224r1 1 +#endif +#ifndef uECC_SUPPORTS_secp256r1 + #define uECC_SUPPORTS_secp256r1 1 +#endif +#ifndef uECC_SUPPORTS_secp256k1 + #define uECC_SUPPORTS_secp256k1 1 +#endif + struct uECC_Curve_t; typedef const struct uECC_Curve_t * uECC_Curve; @@ -30,11 +53,21 @@ extern "C" { #endif +#if uECC_SUPPORTS_secp160r1 uECC_Curve uECC_secp160r1(void); +#endif +#if uECC_SUPPORTS_secp192r1 uECC_Curve uECC_secp192r1(void); +#endif +#if uECC_SUPPORTS_secp224r1 uECC_Curve uECC_secp224r1(void); +#endif +#if uECC_SUPPORTS_secp256r1 uECC_Curve uECC_secp256r1(void); +#endif +#if uECC_SUPPORTS_secp256k1 uECC_Curve uECC_secp256k1(void); +#endif /* uECC_RNG_Function type The RNG function should fill 'size' random bytes into 'dest'. It should return 1 if @@ -261,4 +294,4 @@ int uECC_verify(const uint8_t *private_key, } /* end of extern "C" */ #endif -#endif /* _MICRO_ECC_H_ */ +#endif /* _UECC_H_ */