Crypto: import uecc
This commit is contained in:
parent
e9c42123cb
commit
7df49b62e1
21
vendors/ocaml-uecc/LICENSE.txt
vendored
Normal file
21
vendors/ocaml-uecc/LICENSE.txt
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
Copyright (c) 2014, Kenneth MacKay
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
820
vendors/ocaml-uecc/src/asm_arm.h
vendored
Normal file
820
vendors/ocaml-uecc/src/asm_arm.h
vendored
Normal file
@ -0,0 +1,820 @@
|
|||||||
|
/* Copyright 2015, Kenneth MacKay. Licensed under the BSD 2-clause license. */
|
||||||
|
|
||||||
|
#ifndef _UECC_ASM_ARM_H_
|
||||||
|
#define _UECC_ASM_ARM_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_thumb || uECC_PLATFORM == uECC_arm_thumb2)
|
||||||
|
#define REG_RW_LO "+l"
|
||||||
|
#define REG_WRITE_LO "=l"
|
||||||
|
#else
|
||||||
|
#define REG_RW_LO "+r"
|
||||||
|
#define REG_WRITE_LO "=r"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (uECC_PLATFORM == uECC_arm_thumb2)
|
||||||
|
#define RESUME_SYNTAX
|
||||||
|
#else
|
||||||
|
#define RESUME_SYNTAX ".syntax divided \n\t"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (uECC_OPTIMIZATION_LEVEL >= 2)
|
||||||
|
|
||||||
|
uECC_VLI_API uECC_word_t uECC_vli_add(uECC_word_t *result,
|
||||||
|
const uECC_word_t *left,
|
||||||
|
const uECC_word_t *right,
|
||||||
|
wordcount_t num_words) {
|
||||||
|
#if (uECC_MAX_WORDS != uECC_MIN_WORDS)
|
||||||
|
#if (uECC_PLATFORM == uECC_arm_thumb) || (uECC_PLATFORM == uECC_arm_thumb2)
|
||||||
|
uint32_t jump = (uECC_MAX_WORDS - num_words) * 4 * 2 + 1;
|
||||||
|
#else /* ARM */
|
||||||
|
uint32_t jump = (uECC_MAX_WORDS - num_words) * 4 * 4;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
uint32_t carry;
|
||||||
|
uint32_t left_word;
|
||||||
|
uint32_t right_word;
|
||||||
|
|
||||||
|
__asm__ volatile (
|
||||||
|
".syntax unified \n\t"
|
||||||
|
"movs %[carry], #0 \n\t"
|
||||||
|
#if (uECC_MAX_WORDS != uECC_MIN_WORDS)
|
||||||
|
"adr %[left], 1f \n\t"
|
||||||
|
".align 4 \n\t"
|
||||||
|
"adds %[jump], %[left] \n\t"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
"ldmia %[lptr]!, {%[left]} \n\t"
|
||||||
|
"ldmia %[rptr]!, {%[right]} \n\t"
|
||||||
|
"adds %[left], %[right] \n\t"
|
||||||
|
"stmia %[dptr]!, {%[left]} \n\t"
|
||||||
|
|
||||||
|
#if (uECC_MAX_WORDS != uECC_MIN_WORDS)
|
||||||
|
"bx %[jump] \n\t"
|
||||||
|
#endif
|
||||||
|
"1: \n\t"
|
||||||
|
REPEAT(DEC(uECC_MAX_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"
|
||||||
|
RESUME_SYNTAX
|
||||||
|
: [dptr] REG_RW_LO (result), [lptr] REG_RW_LO (left), [rptr] REG_RW_LO (right),
|
||||||
|
#if (uECC_MAX_WORDS != uECC_MIN_WORDS)
|
||||||
|
[jump] REG_RW_LO (jump),
|
||||||
|
#endif
|
||||||
|
[carry] REG_WRITE_LO (carry), [left] REG_WRITE_LO (left_word),
|
||||||
|
[right] REG_WRITE_LO (right_word)
|
||||||
|
:
|
||||||
|
: "cc", "memory"
|
||||||
|
);
|
||||||
|
return carry;
|
||||||
|
}
|
||||||
|
#define asm_add 1
|
||||||
|
|
||||||
|
uECC_VLI_API uECC_word_t uECC_vli_sub(uECC_word_t *result,
|
||||||
|
const uECC_word_t *left,
|
||||||
|
const uECC_word_t *right,
|
||||||
|
wordcount_t num_words) {
|
||||||
|
#if (uECC_MAX_WORDS != uECC_MIN_WORDS)
|
||||||
|
#if (uECC_PLATFORM == uECC_arm_thumb) || (uECC_PLATFORM == uECC_arm_thumb2)
|
||||||
|
uint32_t jump = (uECC_MAX_WORDS - num_words) * 4 * 2 + 1;
|
||||||
|
#else /* ARM */
|
||||||
|
uint32_t jump = (uECC_MAX_WORDS - num_words) * 4 * 4;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
uint32_t carry;
|
||||||
|
uint32_t left_word;
|
||||||
|
uint32_t right_word;
|
||||||
|
|
||||||
|
__asm__ volatile (
|
||||||
|
".syntax unified \n\t"
|
||||||
|
"movs %[carry], #0 \n\t"
|
||||||
|
#if (uECC_MAX_WORDS != uECC_MIN_WORDS)
|
||||||
|
"adr %[left], 1f \n\t"
|
||||||
|
".align 4 \n\t"
|
||||||
|
"adds %[jump], %[left] \n\t"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
"ldmia %[lptr]!, {%[left]} \n\t"
|
||||||
|
"ldmia %[rptr]!, {%[right]} \n\t"
|
||||||
|
"subs %[left], %[right] \n\t"
|
||||||
|
"stmia %[dptr]!, {%[left]} \n\t"
|
||||||
|
|
||||||
|
#if (uECC_MAX_WORDS != uECC_MIN_WORDS)
|
||||||
|
"bx %[jump] \n\t"
|
||||||
|
#endif
|
||||||
|
"1: \n\t"
|
||||||
|
REPEAT(DEC(uECC_MAX_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"
|
||||||
|
RESUME_SYNTAX
|
||||||
|
: [dptr] REG_RW_LO (result), [lptr] REG_RW_LO (left), [rptr] REG_RW_LO (right),
|
||||||
|
#if (uECC_MAX_WORDS != uECC_MIN_WORDS)
|
||||||
|
[jump] REG_RW_LO (jump),
|
||||||
|
#endif
|
||||||
|
[carry] REG_WRITE_LO (carry), [left] REG_WRITE_LO (left_word),
|
||||||
|
[right] REG_WRITE_LO (right_word)
|
||||||
|
:
|
||||||
|
: "cc", "memory"
|
||||||
|
);
|
||||||
|
return !carry; /* Note that on ARM, carry flag set means "no borrow" when subtracting
|
||||||
|
(for some reason...) */
|
||||||
|
}
|
||||||
|
#define asm_sub 1
|
||||||
|
|
||||||
|
#endif /* (uECC_OPTIMIZATION_LEVEL >= 2) */
|
||||||
|
|
||||||
|
#if (uECC_OPTIMIZATION_LEVEL >= 3)
|
||||||
|
|
||||||
|
#if (uECC_PLATFORM != uECC_arm_thumb)
|
||||||
|
|
||||||
|
#if uECC_ARM_USE_UMAAL
|
||||||
|
#include "asm_arm_mult_square_umaal.h"
|
||||||
|
#else
|
||||||
|
#include "asm_arm_mult_square.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (uECC_OPTIMIZATION_LEVEL == 3)
|
||||||
|
|
||||||
|
uECC_VLI_API void uECC_vli_mult(uint32_t *result,
|
||||||
|
const uint32_t *left,
|
||||||
|
const uint32_t *right,
|
||||||
|
wordcount_t num_words) {
|
||||||
|
register uint32_t *r0 __asm__("r0") = result;
|
||||||
|
register const uint32_t *r1 __asm__("r1") = left;
|
||||||
|
register const uint32_t *r2 __asm__("r2") = right;
|
||||||
|
register uint32_t r3 __asm__("r3") = num_words;
|
||||||
|
|
||||||
|
__asm__ volatile (
|
||||||
|
".syntax unified \n\t"
|
||||||
|
#if (uECC_MIN_WORDS == 5)
|
||||||
|
FAST_MULT_ASM_5
|
||||||
|
#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
|
||||||
|
#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
|
||||||
|
#if (uECC_MAX_WORDS > 7)
|
||||||
|
FAST_MULT_ASM_7_TO_8
|
||||||
|
#endif
|
||||||
|
#elif (uECC_MIN_WORDS == 8)
|
||||||
|
FAST_MULT_ASM_8
|
||||||
|
#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
|
||||||
|
uECC_VLI_API void uECC_vli_square(uECC_word_t *result,
|
||||||
|
const uECC_word_t *left,
|
||||||
|
wordcount_t num_words) {
|
||||||
|
register uint32_t *r0 __asm__("r0") = result;
|
||||||
|
register const uint32_t *r1 __asm__("r1") = left;
|
||||||
|
register uint32_t r2 __asm__("r2") = num_words;
|
||||||
|
|
||||||
|
__asm__ volatile (
|
||||||
|
".syntax unified \n\t"
|
||||||
|
#if (uECC_MIN_WORDS == 5)
|
||||||
|
FAST_SQUARE_ASM_5
|
||||||
|
#if (uECC_MAX_WORDS > 5)
|
||||||
|
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
|
||||||
|
#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 == 7)
|
||||||
|
FAST_SQUARE_ASM_7
|
||||||
|
#if (uECC_MAX_WORDS > 7)
|
||||||
|
FAST_SQUARE_ASM_7_TO_8
|
||||||
|
#endif
|
||||||
|
#elif (uECC_MIN_WORDS == 8)
|
||||||
|
FAST_SQUARE_ASM_8
|
||||||
|
#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 */
|
||||||
|
|
||||||
|
#else /* (uECC_OPTIMIZATION_LEVEL > 3) */
|
||||||
|
|
||||||
|
uECC_VLI_API void uECC_vli_mult(uint32_t *result,
|
||||||
|
const uint32_t *left,
|
||||||
|
const uint32_t *right,
|
||||||
|
wordcount_t num_words) {
|
||||||
|
register uint32_t *r0 __asm__("r0") = result;
|
||||||
|
register const uint32_t *r1 __asm__("r1") = left;
|
||||||
|
register const uint32_t *r2 __asm__("r2") = right;
|
||||||
|
register uint32_t r3 __asm__("r3") = num_words;
|
||||||
|
|
||||||
|
#if uECC_SUPPORTS_secp160r1
|
||||||
|
if (num_words == 5) {
|
||||||
|
__asm__ volatile (
|
||||||
|
".syntax unified \n\t"
|
||||||
|
FAST_MULT_ASM_5
|
||||||
|
RESUME_SYNTAX
|
||||||
|
: "+r" (r0), "+r" (r1), "+r" (r2)
|
||||||
|
: "r" (r3)
|
||||||
|
: "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory"
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if uECC_SUPPORTS_secp192r1
|
||||||
|
if (num_words == 6) {
|
||||||
|
__asm__ volatile (
|
||||||
|
".syntax unified \n\t"
|
||||||
|
FAST_MULT_ASM_6
|
||||||
|
RESUME_SYNTAX
|
||||||
|
: "+r" (r0), "+r" (r1), "+r" (r2)
|
||||||
|
: "r" (r3)
|
||||||
|
: "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory"
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if uECC_SUPPORTS_secp224r1
|
||||||
|
if (num_words == 7) {
|
||||||
|
__asm__ volatile (
|
||||||
|
".syntax unified \n\t"
|
||||||
|
FAST_MULT_ASM_7
|
||||||
|
RESUME_SYNTAX
|
||||||
|
: "+r" (r0), "+r" (r1), "+r" (r2)
|
||||||
|
: "r" (r3)
|
||||||
|
: "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory"
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if (uECC_SUPPORTS_secp256r1 || uECC_SUPPORTS_secp256k1)
|
||||||
|
if (num_words == 8) {
|
||||||
|
__asm__ volatile (
|
||||||
|
".syntax unified \n\t"
|
||||||
|
FAST_MULT_ASM_8
|
||||||
|
RESUME_SYNTAX
|
||||||
|
: "+r" (r0), "+r" (r1), "+r" (r2)
|
||||||
|
: "r" (r3)
|
||||||
|
: "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory"
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#define asm_mult 1
|
||||||
|
|
||||||
|
#if uECC_SQUARE_FUNC
|
||||||
|
uECC_VLI_API void uECC_vli_square(uECC_word_t *result,
|
||||||
|
const uECC_word_t *left,
|
||||||
|
wordcount_t num_words) {
|
||||||
|
register uint32_t *r0 __asm__("r0") = result;
|
||||||
|
register const uint32_t *r1 __asm__("r1") = left;
|
||||||
|
register uint32_t r2 __asm__("r2") = num_words;
|
||||||
|
|
||||||
|
#if uECC_SUPPORTS_secp160r1
|
||||||
|
if (num_words == 5) {
|
||||||
|
__asm__ volatile (
|
||||||
|
".syntax unified \n\t"
|
||||||
|
FAST_SQUARE_ASM_5
|
||||||
|
RESUME_SYNTAX
|
||||||
|
: "+r" (r0), "+r" (r1)
|
||||||
|
: "r" (r2)
|
||||||
|
: "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory"
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if uECC_SUPPORTS_secp192r1
|
||||||
|
if (num_words == 6) {
|
||||||
|
__asm__ volatile (
|
||||||
|
".syntax unified \n\t"
|
||||||
|
FAST_SQUARE_ASM_6
|
||||||
|
RESUME_SYNTAX
|
||||||
|
: "+r" (r0), "+r" (r1)
|
||||||
|
: "r" (r2)
|
||||||
|
: "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory"
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if uECC_SUPPORTS_secp224r1
|
||||||
|
if (num_words == 7) {
|
||||||
|
__asm__ volatile (
|
||||||
|
".syntax unified \n\t"
|
||||||
|
FAST_SQUARE_ASM_7
|
||||||
|
RESUME_SYNTAX
|
||||||
|
: "+r" (r0), "+r" (r1)
|
||||||
|
: "r" (r2)
|
||||||
|
: "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory"
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if (uECC_SUPPORTS_secp256r1 || uECC_SUPPORTS_secp256k1)
|
||||||
|
if (num_words == 8) {
|
||||||
|
__asm__ volatile (
|
||||||
|
".syntax unified \n\t"
|
||||||
|
FAST_SQUARE_ASM_8
|
||||||
|
RESUME_SYNTAX
|
||||||
|
: "+r" (r0), "+r" (r1)
|
||||||
|
: "r" (r2)
|
||||||
|
: "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory"
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#define asm_square 1
|
||||||
|
#endif /* uECC_SQUARE_FUNC */
|
||||||
|
|
||||||
|
#endif /* (uECC_OPTIMIZATION_LEVEL > 3) */
|
||||||
|
|
||||||
|
#endif /* uECC_PLATFORM != uECC_arm_thumb */
|
||||||
|
|
||||||
|
#endif /* (uECC_OPTIMIZATION_LEVEL >= 3) */
|
||||||
|
|
||||||
|
/* ---- "Small" implementations ---- */
|
||||||
|
|
||||||
|
#if !asm_add
|
||||||
|
uECC_VLI_API uECC_word_t uECC_vli_add(uECC_word_t *result,
|
||||||
|
const uECC_word_t *left,
|
||||||
|
const uECC_word_t *right,
|
||||||
|
wordcount_t num_words) {
|
||||||
|
uint32_t carry = 0;
|
||||||
|
uint32_t left_word;
|
||||||
|
uint32_t right_word;
|
||||||
|
|
||||||
|
__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], %[left], %[right] \n\t" /* Add with carry. */
|
||||||
|
"adcs %[carry], %[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. */
|
||||||
|
RESUME_SYNTAX
|
||||||
|
: [dptr] REG_RW (result), [lptr] REG_RW (left), [rptr] REG_RW (right),
|
||||||
|
[ctr] REG_RW (num_words), [carry] REG_RW (carry),
|
||||||
|
[left] REG_WRITE (left_word), [right] REG_WRITE (right_word)
|
||||||
|
:
|
||||||
|
: "cc", "memory"
|
||||||
|
);
|
||||||
|
return carry;
|
||||||
|
}
|
||||||
|
#define asm_add 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !asm_sub
|
||||||
|
uECC_VLI_API uECC_word_t uECC_vli_sub(uECC_word_t *result,
|
||||||
|
const uECC_word_t *left,
|
||||||
|
const uECC_word_t *right,
|
||||||
|
wordcount_t num_words) {
|
||||||
|
uint32_t carry = 1; /* carry = 1 initially (means don't borrow) */
|
||||||
|
uint32_t left_word;
|
||||||
|
uint32_t right_word;
|
||||||
|
|
||||||
|
__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], %[left], %[right] \n\t" /* Subtract with borrow. */
|
||||||
|
"adcs %[carry], %[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. */
|
||||||
|
RESUME_SYNTAX
|
||||||
|
: [dptr] REG_RW (result), [lptr] REG_RW (left), [rptr] REG_RW (right),
|
||||||
|
[ctr] REG_RW (num_words), [carry] REG_RW (carry),
|
||||||
|
[left] REG_WRITE (left_word), [right] REG_WRITE (right_word)
|
||||||
|
:
|
||||||
|
: "cc", "memory"
|
||||||
|
);
|
||||||
|
return !carry;
|
||||||
|
}
|
||||||
|
#define asm_sub 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !asm_mult
|
||||||
|
uECC_VLI_API void uECC_vli_mult(uECC_word_t *result,
|
||||||
|
const uECC_word_t *left,
|
||||||
|
const uECC_word_t *right,
|
||||||
|
wordcount_t num_words) {
|
||||||
|
#if (uECC_PLATFORM != uECC_arm_thumb)
|
||||||
|
uint32_t c0 = 0;
|
||||||
|
uint32_t c1 = 0;
|
||||||
|
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 < num_words) */
|
||||||
|
"movs %[i], #0 \n\t" /* i = 0 */
|
||||||
|
"b 3f \n\t"
|
||||||
|
|
||||||
|
"2: \n\t" /* outer loop (k >= num_words) */
|
||||||
|
"movs %[i], %[k] \n\t" /* i = k */
|
||||||
|
"subs %[i], %[last_word] \n\t" /* i = k - (num_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], %[c0], %[t0] \n\t" /* add low word to c0 */
|
||||||
|
"adcs %[c1], %[c1], %[t1] \n\t" /* add high word to c1, including carry */
|
||||||
|
"adcs %[c2], %[c2], #0 \n\t" /* add carry to c2 */
|
||||||
|
|
||||||
|
"adds %[i], #4 \n\t" /* i += 4 */
|
||||||
|
"cmp %[i], %[last_word] \n\t" /* i > (num_words - 1) (times 4)? */
|
||||||
|
"bgt 4f \n\t" /* if so, 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], %[last_word] \n\t" /* k <= (num_words - 1) (times 4) ? */
|
||||||
|
"ble 1b \n\t" /* if so, loop back, start with i = 0 */
|
||||||
|
"cmp %[k], %[last_word], lsl #1 \n\t" /* k <= (num_words * 2 - 2) (times 4) ? */
|
||||||
|
"ble 2b \n\t" /* if so, loop back, start with i = (k + 1) - num_words */
|
||||||
|
/* end outer loop */
|
||||||
|
|
||||||
|
"str %[c0], [%[result], %[k]] \n\t" /* result[num_words * 2 - 1] = c0 */
|
||||||
|
RESUME_SYNTAX
|
||||||
|
: [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),
|
||||||
|
[last_word] "r" ((num_words - 1) * 4)
|
||||||
|
: "cc", "memory"
|
||||||
|
);
|
||||||
|
|
||||||
|
#else /* Thumb-1 */
|
||||||
|
uint32_t r4, r5, r6, r7;
|
||||||
|
|
||||||
|
__asm__ volatile (
|
||||||
|
".syntax unified \n\t"
|
||||||
|
"subs %[r3], #1 \n\t" /* r3 = num_words - 1 */
|
||||||
|
"lsls %[r3], #2 \n\t" /* r3 = (num_words - 1) * 4 */
|
||||||
|
"mov r8, %[r3] \n\t" /* r8 = (num_words - 1) * 4 */
|
||||||
|
"lsls %[r3], #1 \n\t" /* r3 = (num_words - 1) * 8 */
|
||||||
|
"mov r9, %[r3] \n\t" /* r9 = (num_words - 1) * 8 */
|
||||||
|
"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 < num_words) */
|
||||||
|
"movs %[r7], #0 \n\t" /* r7 = i = 0 */
|
||||||
|
"b 3f \n\t"
|
||||||
|
|
||||||
|
"2: \n\t" /* outer loop (k >= num_words) */
|
||||||
|
"movs %[r7], %[r6] \n\t" /* r7 = k */
|
||||||
|
"mov %[r0], r8 \n\t" /* r0 = (num_words - 1) * 4 */
|
||||||
|
"subs %[r7], %[r0] \n\t" /* r7 = i = k - (num_words - 1) (times 4) */
|
||||||
|
|
||||||
|
"3: \n\t" /* inner loop */
|
||||||
|
"mov r10, %[r3] \n\t"
|
||||||
|
"mov r11, %[r4] \n\t"
|
||||||
|
"mov r12, %[r5] \n\t"
|
||||||
|
"mov r14, %[r6] \n\t"
|
||||||
|
"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 */
|
||||||
|
|
||||||
|
/* Add middle terms */
|
||||||
|
"lsls %[r4], %[r3], #16 \n\t"
|
||||||
|
"lsrs %[r3], %[r3], #16 \n\t"
|
||||||
|
"adds %[r0], %[r4] \n\t"
|
||||||
|
"adcs %[r6], %[r3] \n\t"
|
||||||
|
|
||||||
|
"lsls %[r4], %[r5], #16 \n\t"
|
||||||
|
"lsrs %[r5], %[r5], #16 \n\t"
|
||||||
|
"adds %[r0], %[r4] \n\t"
|
||||||
|
"adcs %[r6], %[r5] \n\t"
|
||||||
|
|
||||||
|
"mov %[r3], r10\n\t"
|
||||||
|
"mov %[r4], r11\n\t"
|
||||||
|
"mov %[r5], r12\n\t"
|
||||||
|
"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 */
|
||||||
|
|
||||||
|
"mov %[r6], r14\n\t" /* r6 = k */
|
||||||
|
|
||||||
|
"adds %[r7], #4 \n\t" /* i += 4 */
|
||||||
|
"cmp %[r7], r8 \n\t" /* i > (num_words - 1) (times 4)? */
|
||||||
|
"bgt 4f \n\t" /* if so, 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], r8 \n\t" /* k <= (num_words - 1) (times 4) ? */
|
||||||
|
"ble 1b \n\t" /* if so, loop back, start with i = 0 */
|
||||||
|
"cmp %[r6], r9 \n\t" /* k <= (num_words * 2 - 2) (times 4) ? */
|
||||||
|
"ble 2b \n\t" /* if so, loop back, with i = (k + 1) - num_words */
|
||||||
|
/* end outer loop */
|
||||||
|
|
||||||
|
"str %[r3], [%[r0], %[r6]] \n\t" /* result[num_words * 2 - 1] = c0 */
|
||||||
|
"pop {%[r0]} \n\t" /* pop result off the stack */
|
||||||
|
|
||||||
|
".syntax divided \n\t"
|
||||||
|
: [r3] "+l" (num_words), [r4] "=&l" (r4),
|
||||||
|
[r5] "=&l" (r5), [r6] "=&l" (r6), [r7] "=&l" (r7)
|
||||||
|
: [r0] "l" (result), [r1] "l" (left), [r2] "l" (right)
|
||||||
|
: "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory"
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#define asm_mult 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if uECC_SQUARE_FUNC
|
||||||
|
#if !asm_square
|
||||||
|
uECC_VLI_API void uECC_vli_square(uECC_word_t *result,
|
||||||
|
const uECC_word_t *left,
|
||||||
|
wordcount_t num_words) {
|
||||||
|
#if (uECC_PLATFORM != uECC_arm_thumb)
|
||||||
|
uint32_t c0 = 0;
|
||||||
|
uint32_t c1 = 0;
|
||||||
|
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 < num_words) */
|
||||||
|
"movs %[i], #0 \n\t" /* i = 0 */
|
||||||
|
"b 3f \n\t"
|
||||||
|
|
||||||
|
"2: \n\t" /* outer loop (k >= num_words) */
|
||||||
|
"movs %[i], %[k] \n\t" /* i = k */
|
||||||
|
"subs %[i], %[last_word] \n\t" /* i = k - (num_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 */
|
||||||
|
"adds %[c0], %[c0], %[t0] \n\t" /* add low word to c0 */
|
||||||
|
"adcs %[c1], %[c1], %[t1] \n\t" /* add high word to c1, including carry */
|
||||||
|
"adcs %[c2], %[c2], #0 \n\t" /* add carry to c2 */
|
||||||
|
|
||||||
|
"4: \n\t"
|
||||||
|
"adds %[c0], %[c0], %[t0] \n\t" /* add low word to c0 */
|
||||||
|
"adcs %[c1], %[c1], %[t1] \n\t" /* add high word to c1, including carry */
|
||||||
|
"adcs %[c2], %[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 so, 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], %[last_word] \n\t" /* k <= (num_words - 1) (times 4) ? */
|
||||||
|
"ble 1b \n\t" /* if so, loop back, start with i = 0 */
|
||||||
|
"cmp %[k], %[last_word], lsl #1 \n\t" /* k <= (num_words * 2 - 2) (times 4) ? */
|
||||||
|
"ble 2b \n\t" /* if so, loop back, start with i = (k + 1) - num_words */
|
||||||
|
/* end outer loop */
|
||||||
|
|
||||||
|
"str %[c0], [%[result], %[k]] \n\t" /* result[num_words * 2 - 1] = c0 */
|
||||||
|
RESUME_SYNTAX
|
||||||
|
: [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), [last_word] "r" ((num_words - 1) * 4)
|
||||||
|
: "cc", "memory"
|
||||||
|
);
|
||||||
|
|
||||||
|
#else
|
||||||
|
uint32_t r3, r4, r5, r6, r7;
|
||||||
|
|
||||||
|
__asm__ volatile (
|
||||||
|
".syntax unified \n\t"
|
||||||
|
"subs %[r2], #1 \n\t" /* r2 = num_words - 1 */
|
||||||
|
"lsls %[r2], #2 \n\t" /* r2 = (num_words - 1) * 4 */
|
||||||
|
"mov r8, %[r2] \n\t" /* r8 = (num_words - 1) * 4 */
|
||||||
|
"lsls %[r2], #1 \n\t" /* r2 = (num_words - 1) * 8 */
|
||||||
|
"mov r9, %[r2] \n\t" /* r9 = (num_words - 1) * 8 */
|
||||||
|
"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 < num_words) */
|
||||||
|
"movs %[r6], #0 \n\t" /* r6 = i = 0 */
|
||||||
|
"b 3f \n\t"
|
||||||
|
|
||||||
|
"2: \n\t" /* outer loop (k >= num_words) */
|
||||||
|
"movs %[r6], %[r5] \n\t" /* r6 = k */
|
||||||
|
"mov %[r0], r8 \n\t" /* r0 = (num_words - 1) * 4 */
|
||||||
|
"subs %[r6], %[r0] \n\t" /* r6 = i = k - (num_words - 1) (times 4) */
|
||||||
|
|
||||||
|
"3: \n\t" /* inner loop */
|
||||||
|
"mov r10, %[r2] \n\t"
|
||||||
|
"mov r11, %[r3] \n\t"
|
||||||
|
"mov r12, %[r4] \n\t"
|
||||||
|
"mov r14, %[r5] \n\t"
|
||||||
|
"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 */
|
||||||
|
|
||||||
|
/* Add middle terms */
|
||||||
|
"lsls %[r3], %[r2], #16 \n\t"
|
||||||
|
"lsrs %[r2], %[r2], #16 \n\t"
|
||||||
|
"adds %[r0], %[r3] \n\t"
|
||||||
|
"adcs %[r5], %[r2] \n\t"
|
||||||
|
|
||||||
|
"lsls %[r3], %[r4], #16 \n\t"
|
||||||
|
"lsrs %[r4], %[r4], #16 \n\t"
|
||||||
|
"adds %[r0], %[r3] \n\t"
|
||||||
|
"adcs %[r5], %[r4] \n\t"
|
||||||
|
|
||||||
|
/* Add to acc, doubling if necessary */
|
||||||
|
"mov %[r2], r10\n\t"
|
||||||
|
"mov %[r3], r11\n\t"
|
||||||
|
"mov %[r4], r12\n\t"
|
||||||
|
|
||||||
|
"cmp %[r6], %[r7] \n\t" /* (i < k - i) ? */
|
||||||
|
"bge 4f \n\t" /* if i >= k - i, skip */
|
||||||
|
"movs %[r7], #0 \n\t" /* r7 = 0 */
|
||||||
|
"adds %[r2], %[r0] \n\t" /* add low word to c0 */
|
||||||
|
"adcs %[r3], %[r5] \n\t" /* add high word to c1, including carry */
|
||||||
|
"adcs %[r4], %[r7] \n\t" /* add carry to c2 */
|
||||||
|
"4: \n\t"
|
||||||
|
"movs %[r7], #0 \n\t" /* r7 = 0 */
|
||||||
|
"adds %[r2], %[r0] \n\t" /* add low word to c0 */
|
||||||
|
"adcs %[r3], %[r5] \n\t" /* add high word to c1, including carry */
|
||||||
|
"adcs %[r4], %[r7] \n\t" /* add carry to c2 */
|
||||||
|
|
||||||
|
"mov %[r5], r14\n\t" /* r5 = k */
|
||||||
|
|
||||||
|
"adds %[r6], #4 \n\t" /* i += 4 */
|
||||||
|
"cmp %[r6], %[r5] \n\t" /* i >= k? */
|
||||||
|
"bge 5f \n\t" /* if so, 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], r8 \n\t" /* k <= (num_words - 1) (times 4) ? */
|
||||||
|
"ble 1b \n\t" /* if so, loop back, start with i = 0 */
|
||||||
|
"cmp %[r5], r9 \n\t" /* k <= (num_words * 2 - 2) (times 4) ? */
|
||||||
|
"ble 2b \n\t" /* if so, loop back, with i = (k + 1) - num_words */
|
||||||
|
/* end outer loop */
|
||||||
|
|
||||||
|
"str %[r2], [%[r0], %[r5]] \n\t" /* result[num_words * 2 - 1] = c0 */
|
||||||
|
"pop {%[r0]} \n\t" /* pop result off the stack */
|
||||||
|
|
||||||
|
".syntax divided \n\t"
|
||||||
|
: [r2] "+l" (num_words), [r3] "=&l" (r3), [r4] "=&l" (r4),
|
||||||
|
[r5] "=&l" (r5), [r6] "=&l" (r6), [r7] "=&l" (r7)
|
||||||
|
: [r0] "l" (result), [r1] "l" (left)
|
||||||
|
: "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory"
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#define asm_square 1
|
||||||
|
#endif
|
||||||
|
#endif /* uECC_SQUARE_FUNC */
|
||||||
|
|
||||||
|
#endif /* _UECC_ASM_ARM_H_ */
|
2311
vendors/ocaml-uecc/src/asm_arm_mult_square.h
vendored
Normal file
2311
vendors/ocaml-uecc/src/asm_arm_mult_square.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1202
vendors/ocaml-uecc/src/asm_arm_mult_square_umaal.h
vendored
Normal file
1202
vendors/ocaml-uecc/src/asm_arm_mult_square_umaal.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1089
vendors/ocaml-uecc/src/asm_avr.h
vendored
Normal file
1089
vendors/ocaml-uecc/src/asm_avr.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1248
vendors/ocaml-uecc/src/curve-specific.h
vendored
Normal file
1248
vendors/ocaml-uecc/src/curve-specific.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
12
vendors/ocaml-uecc/src/jbuild
vendored
Normal file
12
vendors/ocaml-uecc/src/jbuild
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
(jbuild_version 1)
|
||||||
|
|
||||||
|
(library
|
||||||
|
((name uecc)
|
||||||
|
(public_name uecc)
|
||||||
|
(synopsis "ECDH and ECDSA for 8-bit, 32-bit, and 64-bit processors.")
|
||||||
|
(c_names (uECC uecc_stubs))
|
||||||
|
(c_flags (-O3
|
||||||
|
-DuECC_OPTIMIZATION_LEVEL=3
|
||||||
|
-DuECC_SQUARE_FUNC=1
|
||||||
|
-DuECC_VLI_NATIVE_LITTLE_ENDIAN=0))
|
||||||
|
(libraries (bigstring))))
|
69
vendors/ocaml-uecc/src/platform-specific.h
vendored
Normal file
69
vendors/ocaml-uecc/src/platform-specific.h
vendored
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
/* Copyright 2015, Kenneth MacKay. Licensed under the BSD 2-clause license. */
|
||||||
|
|
||||||
|
#ifndef _UECC_PLATFORM_SPECIFIC_H_
|
||||||
|
#define _UECC_PLATFORM_SPECIFIC_H_
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
#if (defined(_WIN32) || defined(_WIN64))
|
||||||
|
/* Windows */
|
||||||
|
|
||||||
|
// use pragma syntax to prevent tweaking the linker script for getting CryptXYZ function
|
||||||
|
#pragma comment(lib, "crypt32.lib")
|
||||||
|
#pragma comment(lib, "advapi32.lib")
|
||||||
|
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <windows.h>
|
||||||
|
#include <wincrypt.h>
|
||||||
|
|
||||||
|
static int default_RNG(uint8_t *dest, unsigned size) {
|
||||||
|
HCRYPTPROV prov;
|
||||||
|
if (!CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CryptGenRandom(prov, size, (BYTE *)dest);
|
||||||
|
CryptReleaseContext(prov, 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#define default_RNG_defined 1
|
||||||
|
|
||||||
|
#elif (defined(__linux__) && (__GLIBC__ > 2 || __GLIBC_MINOR__ > 24)) || (defined __sun)
|
||||||
|
/* Linux and Solaris */
|
||||||
|
|
||||||
|
#include <sys/random.h>
|
||||||
|
static int default_RNG(uint8_t* dest, unsigned size) {
|
||||||
|
ssize_t nb_written = getrandom(dest, size, 0);
|
||||||
|
return ((nb_written == size) ? 1 : 0);
|
||||||
|
}
|
||||||
|
#define default_RNG_defined 1
|
||||||
|
|
||||||
|
#elif defined (__linux__) /* No glibc */
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
static int default_RNG(uint8_t* dest, unsigned size) {
|
||||||
|
int ret;
|
||||||
|
ret = syscall(SYS_getrandom, dest, size, 0);
|
||||||
|
if (ret != size)
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#define default_RNG_defined 1
|
||||||
|
|
||||||
|
#elif defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
|
||||||
|
#include <sys/param.h>
|
||||||
|
#if defined(BSD)
|
||||||
|
/* OSX and BSDs */
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
static int default_RNG(uint8_t* dest, unsigned size) {
|
||||||
|
arc4random_buf(dest, size);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#define default_RNG_defined 1
|
||||||
|
#endif /* defined(BSD) */
|
||||||
|
|
||||||
|
#endif /* platform */
|
||||||
|
|
||||||
|
#endif /* _UECC_PLATFORM_SPECIFIC_H_ */
|
108
vendors/ocaml-uecc/src/types.h
vendored
Normal file
108
vendors/ocaml-uecc/src/types.h
vendored
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
/* Copyright 2015, Kenneth MacKay. Licensed under the BSD 2-clause license. */
|
||||||
|
|
||||||
|
#ifndef _UECC_TYPES_H_
|
||||||
|
#define _UECC_TYPES_H_
|
||||||
|
|
||||||
|
#ifndef uECC_PLATFORM
|
||||||
|
#if __AVR__
|
||||||
|
#define uECC_PLATFORM uECC_avr
|
||||||
|
#elif defined(__thumb2__) || defined(_M_ARMT) /* I think MSVC only supports Thumb-2 targets */
|
||||||
|
#define uECC_PLATFORM uECC_arm_thumb2
|
||||||
|
#elif defined(__thumb__)
|
||||||
|
#define uECC_PLATFORM uECC_arm_thumb
|
||||||
|
#elif defined(__arm__) || defined(_M_ARM)
|
||||||
|
#define uECC_PLATFORM uECC_arm
|
||||||
|
#elif defined(__aarch64__)
|
||||||
|
#define uECC_PLATFORM uECC_arm64
|
||||||
|
#elif defined(__i386__) || defined(_M_IX86) || defined(_X86_) || defined(__I86__)
|
||||||
|
#define uECC_PLATFORM uECC_x86
|
||||||
|
#elif defined(__amd64__) || defined(_M_X64)
|
||||||
|
#define uECC_PLATFORM uECC_x86_64
|
||||||
|
#else
|
||||||
|
#define uECC_PLATFORM uECC_arch_other
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef uECC_ARM_USE_UMAAL
|
||||||
|
#if (uECC_PLATFORM == uECC_arm) && (__ARM_ARCH >= 6)
|
||||||
|
#define uECC_ARM_USE_UMAAL 1
|
||||||
|
#elif (uECC_PLATFORM == uECC_arm_thumb2) && (__ARM_ARCH >= 6) && !__ARM_ARCH_7M__
|
||||||
|
#define uECC_ARM_USE_UMAAL 1
|
||||||
|
#else
|
||||||
|
#define uECC_ARM_USE_UMAAL 0
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef uECC_WORD_SIZE
|
||||||
|
#if uECC_PLATFORM == uECC_avr
|
||||||
|
#define uECC_WORD_SIZE 1
|
||||||
|
#elif (uECC_PLATFORM == uECC_x86_64 || uECC_PLATFORM == uECC_arm64)
|
||||||
|
#define uECC_WORD_SIZE 8
|
||||||
|
#else
|
||||||
|
#define uECC_WORD_SIZE 4
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (uECC_WORD_SIZE != 1) && (uECC_WORD_SIZE != 4) && (uECC_WORD_SIZE != 8)
|
||||||
|
#error "Unsupported value for uECC_WORD_SIZE"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ((uECC_PLATFORM == uECC_avr) && (uECC_WORD_SIZE != 1))
|
||||||
|
#pragma message ("uECC_WORD_SIZE must be 1 for AVR")
|
||||||
|
#undef uECC_WORD_SIZE
|
||||||
|
#define uECC_WORD_SIZE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ((uECC_PLATFORM == uECC_arm || uECC_PLATFORM == uECC_arm_thumb || \
|
||||||
|
uECC_PLATFORM == uECC_arm_thumb2) && \
|
||||||
|
(uECC_WORD_SIZE != 4))
|
||||||
|
#pragma message ("uECC_WORD_SIZE must be 4 for ARM")
|
||||||
|
#undef uECC_WORD_SIZE
|
||||||
|
#define uECC_WORD_SIZE 4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__SIZEOF_INT128__) || ((__clang_major__ * 100 + __clang_minor__) >= 302)
|
||||||
|
#define SUPPORTS_INT128 1
|
||||||
|
#else
|
||||||
|
#define SUPPORTS_INT128 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef int8_t wordcount_t;
|
||||||
|
typedef int16_t bitcount_t;
|
||||||
|
typedef int8_t cmpresult_t;
|
||||||
|
|
||||||
|
#if (uECC_WORD_SIZE == 1)
|
||||||
|
|
||||||
|
typedef uint8_t uECC_word_t;
|
||||||
|
typedef uint16_t uECC_dword_t;
|
||||||
|
|
||||||
|
#define HIGH_BIT_SET 0x80
|
||||||
|
#define uECC_WORD_BITS 8
|
||||||
|
#define uECC_WORD_BITS_SHIFT 3
|
||||||
|
#define uECC_WORD_BITS_MASK 0x07
|
||||||
|
|
||||||
|
#elif (uECC_WORD_SIZE == 4)
|
||||||
|
|
||||||
|
typedef uint32_t uECC_word_t;
|
||||||
|
typedef uint64_t uECC_dword_t;
|
||||||
|
|
||||||
|
#define HIGH_BIT_SET 0x80000000
|
||||||
|
#define uECC_WORD_BITS 32
|
||||||
|
#define uECC_WORD_BITS_SHIFT 5
|
||||||
|
#define uECC_WORD_BITS_MASK 0x01F
|
||||||
|
|
||||||
|
#elif (uECC_WORD_SIZE == 8)
|
||||||
|
|
||||||
|
typedef uint64_t uECC_word_t;
|
||||||
|
#if SUPPORTS_INT128
|
||||||
|
typedef unsigned __int128 uECC_dword_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define HIGH_BIT_SET 0x8000000000000000ull
|
||||||
|
#define uECC_WORD_BITS 64
|
||||||
|
#define uECC_WORD_BITS_SHIFT 6
|
||||||
|
#define uECC_WORD_BITS_MASK 0x03F
|
||||||
|
|
||||||
|
#endif /* uECC_WORD_SIZE */
|
||||||
|
|
||||||
|
#endif /* _UECC_TYPES_H_ */
|
1634
vendors/ocaml-uecc/src/uECC.c
vendored
Normal file
1634
vendors/ocaml-uecc/src/uECC.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
365
vendors/ocaml-uecc/src/uECC.h
vendored
Normal file
365
vendors/ocaml-uecc/src/uECC.h
vendored
Normal file
@ -0,0 +1,365 @@
|
|||||||
|
/* Copyright 2014, Kenneth MacKay. Licensed under the BSD 2-clause license. */
|
||||||
|
|
||||||
|
#ifndef _UECC_H_
|
||||||
|
#define _UECC_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/* Platform selection options.
|
||||||
|
If uECC_PLATFORM is not defined, the code will try to guess it based on compiler macros.
|
||||||
|
Possible values for uECC_PLATFORM are defined below: */
|
||||||
|
#define uECC_arch_other 0
|
||||||
|
#define uECC_x86 1
|
||||||
|
#define uECC_x86_64 2
|
||||||
|
#define uECC_arm 3
|
||||||
|
#define uECC_arm_thumb 4
|
||||||
|
#define uECC_arm_thumb2 5
|
||||||
|
#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.
|
||||||
|
Optimization level 4 currently only has an effect ARM platforms where more than one
|
||||||
|
curve is enabled. */
|
||||||
|
#ifndef uECC_OPTIMIZATION_LEVEL
|
||||||
|
#define uECC_OPTIMIZATION_LEVEL 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* uECC_SQUARE_FUNC - If enabled (defined as nonzero), this will cause a specific function to be
|
||||||
|
used for (scalar) squaring instead of the generic multiplication function. This can make things
|
||||||
|
faster somewhat faster, but increases the code size. */
|
||||||
|
#ifndef uECC_SQUARE_FUNC
|
||||||
|
#define uECC_SQUARE_FUNC 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* uECC_VLI_NATIVE_LITTLE_ENDIAN - If enabled (defined as nonzero), this will switch to native
|
||||||
|
little-endian format for *all* arrays passed in and out of the public API. This includes public
|
||||||
|
and private keys, shared secrets, signatures and message hashes.
|
||||||
|
Using this switch reduces the amount of call stack memory used by uECC, since less intermediate
|
||||||
|
translations are required.
|
||||||
|
Note that this will *only* work on native little-endian processors and it will treat the uint8_t
|
||||||
|
arrays passed into the public API as word arrays, therefore requiring the provided byte arrays
|
||||||
|
to be word aligned on architectures that do not support unaligned accesses.
|
||||||
|
IMPORTANT: Keys and signatures generated with uECC_VLI_NATIVE_LITTLE_ENDIAN=1 are incompatible
|
||||||
|
with keys and signatures generated with uECC_VLI_NATIVE_LITTLE_ENDIAN=0; all parties must use
|
||||||
|
the same endianness. */
|
||||||
|
#ifndef uECC_VLI_NATIVE_LITTLE_ENDIAN
|
||||||
|
#define uECC_VLI_NATIVE_LITTLE_ENDIAN 0
|
||||||
|
#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
|
||||||
|
|
||||||
|
/* Specifies whether compressed point format is supported.
|
||||||
|
Set to 0 to disable point compression/decompression functions. */
|
||||||
|
#ifndef uECC_SUPPORT_COMPRESSED_POINT
|
||||||
|
#define uECC_SUPPORT_COMPRESSED_POINT 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct uECC_Curve_t;
|
||||||
|
typedef const struct uECC_Curve_t * uECC_Curve;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
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
|
||||||
|
'dest' was filled with random data, or 0 if the random data could not be generated.
|
||||||
|
The filled-in values should be either truly random, or from a cryptographically-secure PRNG.
|
||||||
|
|
||||||
|
A correctly functioning RNG function must be set (using uECC_set_rng()) before calling
|
||||||
|
uECC_make_key() or uECC_sign().
|
||||||
|
|
||||||
|
Setting a correctly functioning RNG function improves the resistance to side-channel attacks
|
||||||
|
for uECC_shared_secret() and uECC_sign_deterministic().
|
||||||
|
|
||||||
|
A correct RNG function is set by default when building for Windows, Linux, or OS X.
|
||||||
|
If you are building on another POSIX-compliant system that supports /dev/random or /dev/urandom,
|
||||||
|
you can define uECC_POSIX to use the predefined RNG. For embedded platforms there is no predefined
|
||||||
|
RNG function; you must provide your own.
|
||||||
|
*/
|
||||||
|
typedef int (*uECC_RNG_Function)(uint8_t *dest, unsigned size);
|
||||||
|
|
||||||
|
/* uECC_set_rng() function.
|
||||||
|
Set the function that will be used to generate random bytes. The RNG function should
|
||||||
|
return 1 if the random data was generated, or 0 if the random data could not be generated.
|
||||||
|
|
||||||
|
On platforms where there is no predefined RNG function (eg embedded platforms), this must
|
||||||
|
be called before uECC_make_key() or uECC_sign() are used.
|
||||||
|
|
||||||
|
Inputs:
|
||||||
|
rng_function - The function that will be used to generate random bytes.
|
||||||
|
*/
|
||||||
|
void uECC_set_rng(uECC_RNG_Function rng_function);
|
||||||
|
|
||||||
|
/* uECC_get_rng() function.
|
||||||
|
|
||||||
|
Returns the function that will be used to generate random bytes.
|
||||||
|
*/
|
||||||
|
uECC_RNG_Function uECC_get_rng(void);
|
||||||
|
|
||||||
|
/* uECC_curve_private_key_size() function.
|
||||||
|
|
||||||
|
Returns the size of a private key for the curve in bytes.
|
||||||
|
*/
|
||||||
|
int uECC_curve_private_key_size(uECC_Curve curve);
|
||||||
|
|
||||||
|
/* uECC_curve_public_key_size() function.
|
||||||
|
|
||||||
|
Returns the size of a public key for the curve in bytes.
|
||||||
|
*/
|
||||||
|
int uECC_curve_public_key_size(uECC_Curve curve);
|
||||||
|
|
||||||
|
/* uECC_make_key() function.
|
||||||
|
Create a public/private key pair.
|
||||||
|
|
||||||
|
Outputs:
|
||||||
|
public_key - Will be filled in with the public key. Must be at least 2 * the curve size
|
||||||
|
(in bytes) long. For example, if the curve is secp256r1, public_key must be 64
|
||||||
|
bytes long.
|
||||||
|
private_key - Will be filled in with the private key. Must be as long as the curve order; this
|
||||||
|
is typically the same as the curve size, except for secp160r1. For example, if the
|
||||||
|
curve is secp256r1, private_key must be 32 bytes long.
|
||||||
|
|
||||||
|
For secp160r1, private_key must be 21 bytes long! Note that the first byte will
|
||||||
|
almost always be 0 (there is about a 1 in 2^80 chance of it being non-zero).
|
||||||
|
|
||||||
|
Returns 1 if the key pair was generated successfully, 0 if an error occurred.
|
||||||
|
*/
|
||||||
|
int uECC_make_key(uint8_t *public_key, uint8_t *private_key, uECC_Curve curve);
|
||||||
|
|
||||||
|
/* uECC_shared_secret() function.
|
||||||
|
Compute a shared secret given your secret key and someone else's public key.
|
||||||
|
Note: It is recommended that you hash the result of uECC_shared_secret() before using it for
|
||||||
|
symmetric encryption or HMAC.
|
||||||
|
|
||||||
|
Inputs:
|
||||||
|
public_key - The public key of the remote party.
|
||||||
|
private_key - Your private key.
|
||||||
|
|
||||||
|
Outputs:
|
||||||
|
secret - Will be filled in with the shared secret value. Must be the same size as the
|
||||||
|
curve size; for example, if the curve is secp256r1, secret must be 32 bytes long.
|
||||||
|
|
||||||
|
Returns 1 if the shared secret was generated successfully, 0 if an error occurred.
|
||||||
|
*/
|
||||||
|
int uECC_shared_secret(const uint8_t *public_key,
|
||||||
|
const uint8_t *private_key,
|
||||||
|
uint8_t *secret,
|
||||||
|
uECC_Curve curve);
|
||||||
|
|
||||||
|
#if uECC_SUPPORT_COMPRESSED_POINT
|
||||||
|
/* uECC_compress() function.
|
||||||
|
Compress a public key.
|
||||||
|
|
||||||
|
Inputs:
|
||||||
|
public_key - The public key to compress.
|
||||||
|
|
||||||
|
Outputs:
|
||||||
|
compressed - Will be filled in with the compressed public key. Must be at least
|
||||||
|
(curve size + 1) bytes long; for example, if the curve is secp256r1,
|
||||||
|
compressed must be 33 bytes long.
|
||||||
|
*/
|
||||||
|
void uECC_compress(const uint8_t *public_key, uint8_t *compressed, uECC_Curve curve);
|
||||||
|
|
||||||
|
/* uECC_decompress() function.
|
||||||
|
Decompress a compressed public key.
|
||||||
|
|
||||||
|
Inputs:
|
||||||
|
compressed - The compressed public key.
|
||||||
|
|
||||||
|
Outputs:
|
||||||
|
public_key - Will be filled in with the decompressed public key.
|
||||||
|
*/
|
||||||
|
void uECC_decompress(const uint8_t *compressed, uint8_t *public_key, uECC_Curve curve);
|
||||||
|
#endif /* uECC_SUPPORT_COMPRESSED_POINT */
|
||||||
|
|
||||||
|
/* uECC_valid_public_key() function.
|
||||||
|
Check to see if a public key is valid.
|
||||||
|
|
||||||
|
Note that you are not required to check for a valid public key before using any other uECC
|
||||||
|
functions. However, you may wish to avoid spending CPU time computing a shared secret or
|
||||||
|
verifying a signature using an invalid public key.
|
||||||
|
|
||||||
|
Inputs:
|
||||||
|
public_key - The public key to check.
|
||||||
|
|
||||||
|
Returns 1 if the public key is valid, 0 if it is invalid.
|
||||||
|
*/
|
||||||
|
int uECC_valid_public_key(const uint8_t *public_key, uECC_Curve curve);
|
||||||
|
|
||||||
|
/* uECC_compute_public_key() function.
|
||||||
|
Compute the corresponding public key for a private key.
|
||||||
|
|
||||||
|
Inputs:
|
||||||
|
private_key - The private key to compute the public key for
|
||||||
|
|
||||||
|
Outputs:
|
||||||
|
public_key - Will be filled in with the corresponding public key
|
||||||
|
|
||||||
|
Returns 1 if the key was computed successfully, 0 if an error occurred.
|
||||||
|
*/
|
||||||
|
int uECC_compute_public_key(const uint8_t *private_key, uint8_t *public_key, uECC_Curve curve);
|
||||||
|
|
||||||
|
/* uECC_sign() function.
|
||||||
|
Generate an ECDSA signature for a given hash value.
|
||||||
|
|
||||||
|
Usage: Compute a hash of the data you wish to sign (SHA-2 is recommended) and pass it in to
|
||||||
|
this function along with your private key.
|
||||||
|
|
||||||
|
Inputs:
|
||||||
|
private_key - Your private key.
|
||||||
|
message_hash - The hash of the message to sign.
|
||||||
|
hash_size - The size of message_hash in bytes.
|
||||||
|
|
||||||
|
Outputs:
|
||||||
|
signature - Will be filled in with the signature value. Must be at least 2 * curve size long.
|
||||||
|
For example, if the curve is secp256r1, signature must be 64 bytes long.
|
||||||
|
|
||||||
|
Returns 1 if the signature generated successfully, 0 if an error occurred.
|
||||||
|
*/
|
||||||
|
int uECC_sign(const uint8_t *private_key,
|
||||||
|
const uint8_t *message_hash,
|
||||||
|
unsigned hash_size,
|
||||||
|
uint8_t *signature,
|
||||||
|
uECC_Curve curve);
|
||||||
|
|
||||||
|
/* uECC_HashContext structure.
|
||||||
|
This is used to pass in an arbitrary hash function to uECC_sign_deterministic().
|
||||||
|
The structure will be used for multiple hash computations; each time a new hash
|
||||||
|
is computed, init_hash() will be called, followed by one or more calls to
|
||||||
|
update_hash(), and finally a call to finish_hash() to produce the resulting hash.
|
||||||
|
|
||||||
|
The intention is that you will create a structure that includes uECC_HashContext
|
||||||
|
followed by any hash-specific data. For example:
|
||||||
|
|
||||||
|
typedef struct SHA256_HashContext {
|
||||||
|
uECC_HashContext uECC;
|
||||||
|
SHA256_CTX ctx;
|
||||||
|
} SHA256_HashContext;
|
||||||
|
|
||||||
|
void init_SHA256(uECC_HashContext *base) {
|
||||||
|
SHA256_HashContext *context = (SHA256_HashContext *)base;
|
||||||
|
SHA256_Init(&context->ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void update_SHA256(uECC_HashContext *base,
|
||||||
|
const uint8_t *message,
|
||||||
|
unsigned message_size) {
|
||||||
|
SHA256_HashContext *context = (SHA256_HashContext *)base;
|
||||||
|
SHA256_Update(&context->ctx, message, message_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void finish_SHA256(uECC_HashContext *base, uint8_t *hash_result) {
|
||||||
|
SHA256_HashContext *context = (SHA256_HashContext *)base;
|
||||||
|
SHA256_Final(hash_result, &context->ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
... when signing ...
|
||||||
|
{
|
||||||
|
uint8_t tmp[32 + 32 + 64];
|
||||||
|
SHA256_HashContext ctx = {{&init_SHA256, &update_SHA256, &finish_SHA256, 64, 32, tmp}};
|
||||||
|
uECC_sign_deterministic(key, message_hash, &ctx.uECC, signature);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
typedef struct uECC_HashContext {
|
||||||
|
void (*init_hash)(const struct uECC_HashContext *context);
|
||||||
|
void (*update_hash)(const struct uECC_HashContext *context,
|
||||||
|
const uint8_t *message,
|
||||||
|
unsigned message_size);
|
||||||
|
void (*finish_hash)(const struct uECC_HashContext *context, uint8_t *hash_result);
|
||||||
|
unsigned block_size; /* Hash function block size in bytes, eg 64 for SHA-256. */
|
||||||
|
unsigned result_size; /* Hash function result size in bytes, eg 32 for SHA-256. */
|
||||||
|
uint8_t *tmp; /* Must point to a buffer of at least (2 * result_size + block_size) bytes. */
|
||||||
|
} uECC_HashContext;
|
||||||
|
|
||||||
|
/* uECC_sign_deterministic() function.
|
||||||
|
Generate an ECDSA signature for a given hash value, using a deterministic algorithm
|
||||||
|
(see RFC 6979). You do not need to set the RNG using uECC_set_rng() before calling
|
||||||
|
this function; however, if the RNG is defined it will improve resistance to side-channel
|
||||||
|
attacks.
|
||||||
|
|
||||||
|
Usage: Compute a hash of the data you wish to sign (SHA-2 is recommended) and pass it to
|
||||||
|
this function along with your private key and a hash context. Note that the message_hash
|
||||||
|
does not need to be computed with the same hash function used by hash_context.
|
||||||
|
|
||||||
|
Inputs:
|
||||||
|
private_key - Your private key.
|
||||||
|
message_hash - The hash of the message to sign.
|
||||||
|
hash_size - The size of message_hash in bytes.
|
||||||
|
hash_context - A hash context to use.
|
||||||
|
|
||||||
|
Outputs:
|
||||||
|
signature - Will be filled in with the signature value.
|
||||||
|
|
||||||
|
Returns 1 if the signature generated successfully, 0 if an error occurred.
|
||||||
|
*/
|
||||||
|
int uECC_sign_deterministic(const uint8_t *private_key,
|
||||||
|
const uint8_t *message_hash,
|
||||||
|
unsigned hash_size,
|
||||||
|
const uECC_HashContext *hash_context,
|
||||||
|
uint8_t *signature,
|
||||||
|
uECC_Curve curve);
|
||||||
|
|
||||||
|
/* uECC_verify() function.
|
||||||
|
Verify an ECDSA signature.
|
||||||
|
|
||||||
|
Usage: Compute the hash of the signed data using the same hash as the signer and
|
||||||
|
pass it to this function along with the signer's public key and the signature values (r and s).
|
||||||
|
|
||||||
|
Inputs:
|
||||||
|
public_key - The signer's public key.
|
||||||
|
message_hash - The hash of the signed data.
|
||||||
|
hash_size - The size of message_hash in bytes.
|
||||||
|
signature - The signature value.
|
||||||
|
|
||||||
|
Returns 1 if the signature is valid, 0 if it is invalid.
|
||||||
|
*/
|
||||||
|
int uECC_verify(const uint8_t *public_key,
|
||||||
|
const uint8_t *message_hash,
|
||||||
|
unsigned hash_size,
|
||||||
|
const uint8_t *signature,
|
||||||
|
uECC_Curve curve);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* end of extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _UECC_H_ */
|
172
vendors/ocaml-uecc/src/uECC_vli.h
vendored
Normal file
172
vendors/ocaml-uecc/src/uECC_vli.h
vendored
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
/* Copyright 2015, Kenneth MacKay. Licensed under the BSD 2-clause license. */
|
||||||
|
|
||||||
|
#ifndef _UECC_VLI_H_
|
||||||
|
#define _UECC_VLI_H_
|
||||||
|
|
||||||
|
#include "uECC.h"
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
/* Functions for raw large-integer manipulation. These are only available
|
||||||
|
if uECC.c is compiled with uECC_ENABLE_VLI_API defined to 1. */
|
||||||
|
#ifndef uECC_ENABLE_VLI_API
|
||||||
|
#define uECC_ENABLE_VLI_API 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if uECC_ENABLE_VLI_API
|
||||||
|
|
||||||
|
void uECC_vli_clear(uECC_word_t *vli, wordcount_t num_words);
|
||||||
|
|
||||||
|
/* Constant-time comparison to zero - secure way to compare long integers */
|
||||||
|
/* Returns 1 if vli == 0, 0 otherwise. */
|
||||||
|
uECC_word_t uECC_vli_isZero(const uECC_word_t *vli, wordcount_t num_words);
|
||||||
|
|
||||||
|
/* Returns nonzero if bit 'bit' of vli is set. */
|
||||||
|
uECC_word_t uECC_vli_testBit(const uECC_word_t *vli, bitcount_t bit);
|
||||||
|
|
||||||
|
/* Counts the number of bits required to represent vli. */
|
||||||
|
bitcount_t uECC_vli_numBits(const uECC_word_t *vli, const wordcount_t max_words);
|
||||||
|
|
||||||
|
/* Sets dest = src. */
|
||||||
|
void uECC_vli_set(uECC_word_t *dest, const uECC_word_t *src, wordcount_t num_words);
|
||||||
|
|
||||||
|
/* Constant-time comparison function - secure way to compare long integers */
|
||||||
|
/* Returns one if left == right, zero otherwise */
|
||||||
|
uECC_word_t uECC_vli_equal(const uECC_word_t *left,
|
||||||
|
const uECC_word_t *right,
|
||||||
|
wordcount_t num_words);
|
||||||
|
|
||||||
|
/* Constant-time comparison function - secure way to compare long integers */
|
||||||
|
/* Returns sign of left - right, in constant time. */
|
||||||
|
cmpresult_t uECC_vli_cmp(const uECC_word_t *left, const uECC_word_t *right, wordcount_t num_words);
|
||||||
|
|
||||||
|
/* Computes vli = vli >> 1. */
|
||||||
|
void uECC_vli_rshift1(uECC_word_t *vli, wordcount_t num_words);
|
||||||
|
|
||||||
|
/* Computes result = left + right, returning carry. Can modify in place. */
|
||||||
|
uECC_word_t uECC_vli_add(uECC_word_t *result,
|
||||||
|
const uECC_word_t *left,
|
||||||
|
const uECC_word_t *right,
|
||||||
|
wordcount_t num_words);
|
||||||
|
|
||||||
|
/* Computes result = left - right, returning borrow. Can modify in place. */
|
||||||
|
uECC_word_t uECC_vli_sub(uECC_word_t *result,
|
||||||
|
const uECC_word_t *left,
|
||||||
|
const uECC_word_t *right,
|
||||||
|
wordcount_t num_words);
|
||||||
|
|
||||||
|
/* Computes result = left * right. Result must be 2 * num_words long. */
|
||||||
|
void uECC_vli_mult(uECC_word_t *result,
|
||||||
|
const uECC_word_t *left,
|
||||||
|
const uECC_word_t *right,
|
||||||
|
wordcount_t num_words);
|
||||||
|
|
||||||
|
/* Computes result = left^2. Result must be 2 * num_words long. */
|
||||||
|
void uECC_vli_square(uECC_word_t *result, const uECC_word_t *left, wordcount_t num_words);
|
||||||
|
|
||||||
|
/* Computes result = (left + right) % mod.
|
||||||
|
Assumes that left < mod and right < mod, and that result does not overlap mod. */
|
||||||
|
void uECC_vli_modAdd(uECC_word_t *result,
|
||||||
|
const uECC_word_t *left,
|
||||||
|
const uECC_word_t *right,
|
||||||
|
const uECC_word_t *mod,
|
||||||
|
wordcount_t num_words);
|
||||||
|
|
||||||
|
/* Computes result = (left - right) % mod.
|
||||||
|
Assumes that left < mod and right < mod, and that result does not overlap mod. */
|
||||||
|
void uECC_vli_modSub(uECC_word_t *result,
|
||||||
|
const uECC_word_t *left,
|
||||||
|
const uECC_word_t *right,
|
||||||
|
const uECC_word_t *mod,
|
||||||
|
wordcount_t num_words);
|
||||||
|
|
||||||
|
/* Computes result = product % mod, where product is 2N words long.
|
||||||
|
Currently only designed to work for mod == curve->p or curve_n. */
|
||||||
|
void uECC_vli_mmod(uECC_word_t *result,
|
||||||
|
uECC_word_t *product,
|
||||||
|
const uECC_word_t *mod,
|
||||||
|
wordcount_t num_words);
|
||||||
|
|
||||||
|
/* Calculates result = product (mod curve->p), where product is up to
|
||||||
|
2 * curve->num_words long. */
|
||||||
|
void uECC_vli_mmod_fast(uECC_word_t *result, uECC_word_t *product, uECC_Curve curve);
|
||||||
|
|
||||||
|
/* Computes result = (left * right) % mod.
|
||||||
|
Currently only designed to work for mod == curve->p or curve_n. */
|
||||||
|
void uECC_vli_modMult(uECC_word_t *result,
|
||||||
|
const uECC_word_t *left,
|
||||||
|
const uECC_word_t *right,
|
||||||
|
const uECC_word_t *mod,
|
||||||
|
wordcount_t num_words);
|
||||||
|
|
||||||
|
/* Computes result = (left * right) % curve->p. */
|
||||||
|
void uECC_vli_modMult_fast(uECC_word_t *result,
|
||||||
|
const uECC_word_t *left,
|
||||||
|
const uECC_word_t *right,
|
||||||
|
uECC_Curve curve);
|
||||||
|
|
||||||
|
/* Computes result = left^2 % mod.
|
||||||
|
Currently only designed to work for mod == curve->p or curve_n. */
|
||||||
|
void uECC_vli_modSquare(uECC_word_t *result,
|
||||||
|
const uECC_word_t *left,
|
||||||
|
const uECC_word_t *mod,
|
||||||
|
wordcount_t num_words);
|
||||||
|
|
||||||
|
/* Computes result = left^2 % curve->p. */
|
||||||
|
void uECC_vli_modSquare_fast(uECC_word_t *result, const uECC_word_t *left, uECC_Curve curve);
|
||||||
|
|
||||||
|
/* Computes result = (1 / input) % mod.*/
|
||||||
|
void uECC_vli_modInv(uECC_word_t *result,
|
||||||
|
const uECC_word_t *input,
|
||||||
|
const uECC_word_t *mod,
|
||||||
|
wordcount_t num_words);
|
||||||
|
|
||||||
|
#if uECC_SUPPORT_COMPRESSED_POINT
|
||||||
|
/* Calculates a = sqrt(a) (mod curve->p) */
|
||||||
|
void uECC_vli_mod_sqrt(uECC_word_t *a, uECC_Curve curve);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Converts an integer in uECC native format to big-endian bytes. */
|
||||||
|
void uECC_vli_nativeToBytes(uint8_t *bytes, int num_bytes, const uECC_word_t *native);
|
||||||
|
/* Converts big-endian bytes to an integer in uECC native format. */
|
||||||
|
void uECC_vli_bytesToNative(uECC_word_t *native, const uint8_t *bytes, int num_bytes);
|
||||||
|
|
||||||
|
unsigned uECC_curve_num_words(uECC_Curve curve);
|
||||||
|
unsigned uECC_curve_num_bytes(uECC_Curve curve);
|
||||||
|
unsigned uECC_curve_num_bits(uECC_Curve curve);
|
||||||
|
unsigned uECC_curve_num_n_words(uECC_Curve curve);
|
||||||
|
unsigned uECC_curve_num_n_bytes(uECC_Curve curve);
|
||||||
|
unsigned uECC_curve_num_n_bits(uECC_Curve curve);
|
||||||
|
|
||||||
|
const uECC_word_t *uECC_curve_p(uECC_Curve curve);
|
||||||
|
const uECC_word_t *uECC_curve_n(uECC_Curve curve);
|
||||||
|
const uECC_word_t *uECC_curve_G(uECC_Curve curve);
|
||||||
|
const uECC_word_t *uECC_curve_b(uECC_Curve curve);
|
||||||
|
|
||||||
|
int uECC_valid_point(const uECC_word_t *point, uECC_Curve curve);
|
||||||
|
|
||||||
|
/* Multiplies a point by a scalar. Points are represented by the X coordinate followed by
|
||||||
|
the Y coordinate in the same array, both coordinates are curve->num_words long. Note
|
||||||
|
that scalar must be curve->num_n_words long (NOT curve->num_words). */
|
||||||
|
void uECC_point_mult(uECC_word_t *result,
|
||||||
|
const uECC_word_t *point,
|
||||||
|
const uECC_word_t *scalar,
|
||||||
|
uECC_Curve curve);
|
||||||
|
|
||||||
|
/* Generates a random integer in the range 0 < random < top.
|
||||||
|
Both random and top have num_words words. */
|
||||||
|
int uECC_generate_random_int(uECC_word_t *random,
|
||||||
|
const uECC_word_t *top,
|
||||||
|
wordcount_t num_words);
|
||||||
|
|
||||||
|
#endif /* uECC_ENABLE_VLI_API */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* end of extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _UECC_VLI_H_ */
|
248
vendors/ocaml-uecc/src/uecc.ml
vendored
Normal file
248
vendors/ocaml-uecc/src/uecc.ml
vendored
Normal file
@ -0,0 +1,248 @@
|
|||||||
|
(*---------------------------------------------------------------------------
|
||||||
|
Copyright (c) 2017 Vincent Bernardoff. All rights reserved.
|
||||||
|
Distributed under the ISC license, see terms at the end of the file.
|
||||||
|
---------------------------------------------------------------------------*)
|
||||||
|
|
||||||
|
type curve
|
||||||
|
|
||||||
|
type secp160r1
|
||||||
|
type secp192r1
|
||||||
|
type secp224r1
|
||||||
|
type secp256r1
|
||||||
|
type secp256k1
|
||||||
|
|
||||||
|
type _ t =
|
||||||
|
| Secp160r1 : curve -> secp160r1 t
|
||||||
|
| Secp192r1 : curve -> secp192r1 t
|
||||||
|
| Secp224r1 : curve -> secp224r1 t
|
||||||
|
| Secp256r1 : curve -> secp256r1 t
|
||||||
|
| Secp256k1 : curve -> secp256k1 t
|
||||||
|
|
||||||
|
external curve : int -> curve = "uECC_curve_stub"
|
||||||
|
external sk_size : curve -> int = "uECC_curve_private_key_size_stub" [@@noalloc]
|
||||||
|
external pk_size : curve -> int = "uECC_curve_public_key_size_stub" [@@noalloc]
|
||||||
|
|
||||||
|
let sk_sizes = Hashtbl.create 5
|
||||||
|
let pk_sizes = Hashtbl.create 5
|
||||||
|
|
||||||
|
let secp160r1 =
|
||||||
|
let c = curve 0 in
|
||||||
|
Hashtbl.add sk_sizes c (sk_size c) ;
|
||||||
|
Hashtbl.add pk_sizes c (pk_size c) ;
|
||||||
|
Secp160r1 c
|
||||||
|
let secp192r1 =
|
||||||
|
let c = curve 1 in
|
||||||
|
Hashtbl.add sk_sizes c (sk_size c) ;
|
||||||
|
Hashtbl.add pk_sizes c (pk_size c) ;
|
||||||
|
Secp192r1 c
|
||||||
|
let secp224r1 =
|
||||||
|
let c = curve 2 in
|
||||||
|
Hashtbl.add sk_sizes c (sk_size c) ;
|
||||||
|
Hashtbl.add pk_sizes c (pk_size c) ;
|
||||||
|
Secp224r1 c
|
||||||
|
let secp256r1 =
|
||||||
|
let c = curve 3 in
|
||||||
|
Hashtbl.add sk_sizes c (sk_size c) ;
|
||||||
|
Hashtbl.add pk_sizes c (pk_size c) ;
|
||||||
|
Secp256r1 c
|
||||||
|
let secp256k1 =
|
||||||
|
let c = curve 4 in
|
||||||
|
Hashtbl.add sk_sizes c (sk_size c) ;
|
||||||
|
Hashtbl.add pk_sizes c (pk_size c) ;
|
||||||
|
Secp256k1 c
|
||||||
|
|
||||||
|
let to_curve : type a. a t -> curve = function
|
||||||
|
| Secp160r1 curve -> curve
|
||||||
|
| Secp192r1 curve -> curve
|
||||||
|
| Secp224r1 curve -> curve
|
||||||
|
| Secp256r1 curve -> curve
|
||||||
|
| Secp256k1 curve -> curve
|
||||||
|
|
||||||
|
let sk_size : type a. a t -> int = function
|
||||||
|
| Secp160r1 curve -> Hashtbl.find sk_sizes curve
|
||||||
|
| Secp192r1 curve -> Hashtbl.find sk_sizes curve
|
||||||
|
| Secp224r1 curve -> Hashtbl.find sk_sizes curve
|
||||||
|
| Secp256r1 curve -> Hashtbl.find sk_sizes curve
|
||||||
|
| Secp256k1 curve -> Hashtbl.find sk_sizes curve
|
||||||
|
|
||||||
|
let pk_size : type a. a t -> int = function
|
||||||
|
| Secp160r1 curve -> Hashtbl.find pk_sizes curve
|
||||||
|
| Secp192r1 curve -> Hashtbl.find pk_sizes curve
|
||||||
|
| Secp224r1 curve -> Hashtbl.find pk_sizes curve
|
||||||
|
| Secp256r1 curve -> Hashtbl.find pk_sizes curve
|
||||||
|
| Secp256k1 curve -> Hashtbl.find pk_sizes curve
|
||||||
|
|
||||||
|
let compressed_size k =
|
||||||
|
pk_size k / 2 + 1
|
||||||
|
|
||||||
|
external keypair :
|
||||||
|
Bigstring.t -> Bigstring.t -> curve -> bool = "uECC_make_key_stub" [@@noalloc]
|
||||||
|
|
||||||
|
external pk_of_sk :
|
||||||
|
Bigstring.t -> Bigstring.t -> curve -> bool = "uECC_compute_public_key_stub" [@@noalloc]
|
||||||
|
external valid_pk :
|
||||||
|
Bigstring.t -> curve -> bool = "uECC_valid_public_key_stub" [@@noalloc]
|
||||||
|
|
||||||
|
external compress :
|
||||||
|
Bigstring.t -> Bigstring.t -> curve -> unit = "uECC_compress_stub" [@@noalloc]
|
||||||
|
external decompress :
|
||||||
|
Bigstring.t -> Bigstring.t -> curve -> unit = "uECC_decompress_stub" [@@noalloc]
|
||||||
|
|
||||||
|
type secret
|
||||||
|
type public
|
||||||
|
|
||||||
|
type (_, _) key =
|
||||||
|
| Sk : Bigstring.t * 'a t -> ('a, secret) key
|
||||||
|
| Pk : Bigstring.t * 'a t -> ('a, public) key
|
||||||
|
|
||||||
|
let equal : type a b. (a, b) key -> (a, b) key -> bool = fun k1 k2 ->
|
||||||
|
match k1, k2 with
|
||||||
|
| Sk (sk, _), Sk (sk2, _) -> Bigstring.equal sk sk2
|
||||||
|
| Pk (pk, c), Pk (pk2, _) ->
|
||||||
|
let len = compressed_size c in
|
||||||
|
let cpk = Bigstring.create len in
|
||||||
|
let cpk2 = Bigstring.create len in
|
||||||
|
compress pk cpk (to_curve c) ;
|
||||||
|
compress pk2 cpk2 (to_curve c) ;
|
||||||
|
Bigstring.equal cpk cpk2
|
||||||
|
|
||||||
|
let neuterize : type a b. (a, b) key -> (a, public) key = function
|
||||||
|
| Pk (pk, curve) -> Pk (pk, curve)
|
||||||
|
| Sk (sk, curve) ->
|
||||||
|
let pk = Bigstring.create (pk_size curve) in
|
||||||
|
let pk_computed_ok = pk_of_sk sk pk (to_curve curve) in
|
||||||
|
let pk_is_valid = valid_pk pk (to_curve curve) in
|
||||||
|
if not pk_computed_ok && pk_is_valid then
|
||||||
|
invalid_arg "Uecc.neuterize" ;
|
||||||
|
Pk (pk, curve)
|
||||||
|
|
||||||
|
let pk_of_bytes :
|
||||||
|
type a. a t -> Bigstring.t ->
|
||||||
|
((a, public) key) option = fun curve buf ->
|
||||||
|
match Bigstring.length buf with
|
||||||
|
| len when len = compressed_size curve ->
|
||||||
|
let c = to_curve curve in
|
||||||
|
let pk = Bigstring.create (pk_size curve) in
|
||||||
|
decompress buf pk c ;
|
||||||
|
if valid_pk pk c then Some (Pk (pk, curve))
|
||||||
|
else None
|
||||||
|
| len when len = pk_size curve + 1 ->
|
||||||
|
let c = to_curve curve in
|
||||||
|
let pk = Bigstring.create (pk_size curve) in
|
||||||
|
Bigstring.blit buf 1 pk 0 (len - 1) ;
|
||||||
|
if Bigstring.get buf 0 = '\004' && valid_pk pk c then
|
||||||
|
Some (Pk (pk, curve))
|
||||||
|
else None
|
||||||
|
| _ -> None
|
||||||
|
|
||||||
|
let sk_of_bytes :
|
||||||
|
type a. a t -> Bigstring.t ->
|
||||||
|
((a, secret) key * (a, public) key) option = fun curve buf ->
|
||||||
|
if Bigstring.length buf <> sk_size curve then None
|
||||||
|
else
|
||||||
|
let sk = Sk (Bigstring.copy buf, curve) in
|
||||||
|
try
|
||||||
|
let pk = neuterize sk in
|
||||||
|
Some (sk, pk)
|
||||||
|
with _ -> None
|
||||||
|
|
||||||
|
let to_bytes :
|
||||||
|
type a b. ?compress:bool -> (a, b) key -> Bigstring.t =
|
||||||
|
fun ?compress:(comp=true) -> function
|
||||||
|
| Sk (sk, _) -> Bigstring.copy sk
|
||||||
|
| Pk (pk, c) ->
|
||||||
|
if comp then
|
||||||
|
let buf = Bigstring.create (compressed_size c) in
|
||||||
|
compress pk buf (to_curve c) ;
|
||||||
|
buf
|
||||||
|
else
|
||||||
|
let len = pk_size c in
|
||||||
|
let buf = Bigstring.create (len + 1) in
|
||||||
|
Bigstring.set buf 0 '\004' ;
|
||||||
|
Bigstring.blit pk 0 buf 1 len ;
|
||||||
|
buf
|
||||||
|
|
||||||
|
let write_key :
|
||||||
|
type a b. ?compress:bool -> Bigstring.t -> (a, b) key -> int =
|
||||||
|
fun ?compress:(comp=true) buf -> function
|
||||||
|
| Sk (sk, _) ->
|
||||||
|
let len = Bigstring.length sk in
|
||||||
|
Bigstring.blit sk 0 buf 0 len ;
|
||||||
|
len
|
||||||
|
| Pk (pk, c) ->
|
||||||
|
if comp then begin
|
||||||
|
compress pk buf (to_curve c) ;
|
||||||
|
compressed_size c
|
||||||
|
end
|
||||||
|
else
|
||||||
|
let len = Bigstring.length pk in
|
||||||
|
Bigstring.set buf 0 '\004' ;
|
||||||
|
Bigstring.blit pk 0 buf 1 len ;
|
||||||
|
len + 1
|
||||||
|
|
||||||
|
let keypair :
|
||||||
|
type a. a t -> ((a, secret) key * (a, public) key) option = fun t ->
|
||||||
|
let sk = Bigstring.create (sk_size t) in
|
||||||
|
let pk = Bigstring.create (pk_size t) in
|
||||||
|
match keypair pk sk (to_curve t) with
|
||||||
|
| true -> Some (Sk (sk, t), Pk (pk, t))
|
||||||
|
| false -> None
|
||||||
|
|
||||||
|
external dh :
|
||||||
|
Bigstring.t -> Bigstring.t -> Bigstring.t -> curve -> bool =
|
||||||
|
"uECC_shared_secret_stub" [@@noalloc]
|
||||||
|
|
||||||
|
let write_dh (Sk (sk, c)) (Pk (pk, _)) buf =
|
||||||
|
let secret_len = pk_size c / 2 in
|
||||||
|
if Bigstring.length buf < secret_len then 0
|
||||||
|
else
|
||||||
|
match dh pk sk buf (to_curve c) with
|
||||||
|
| true -> secret_len
|
||||||
|
| false -> 0
|
||||||
|
|
||||||
|
let dh (Sk (sk, c)) (Pk (pk, _)) =
|
||||||
|
let secret = Bigstring.create (pk_size c / 2) in
|
||||||
|
match dh pk sk secret (to_curve c) with
|
||||||
|
| true -> Some secret
|
||||||
|
| false -> None
|
||||||
|
|
||||||
|
external sign :
|
||||||
|
Bigstring.t -> Bigstring.t -> Bigstring.t -> curve -> bool =
|
||||||
|
"uECC_sign_stub" [@@noalloc]
|
||||||
|
|
||||||
|
external verify :
|
||||||
|
Bigstring.t -> Bigstring.t -> Bigstring.t -> curve -> bool =
|
||||||
|
"uECC_verify_stub" [@@noalloc]
|
||||||
|
|
||||||
|
let write_sign (Sk (sk, c)) buf ~msg =
|
||||||
|
if Bigstring.length buf < pk_size c then 0
|
||||||
|
else
|
||||||
|
match sign sk msg buf (to_curve c) with
|
||||||
|
| true -> pk_size c
|
||||||
|
| false -> 0
|
||||||
|
|
||||||
|
let sign (Sk (sk, c)) msg =
|
||||||
|
let signature = Bigstring.create (pk_size c) in
|
||||||
|
match sign sk msg signature (to_curve c) with
|
||||||
|
| true -> Some signature
|
||||||
|
| false -> None
|
||||||
|
|
||||||
|
let verify (Pk (pk, c)) ~msg ~signature =
|
||||||
|
if Bigstring.length signature <> pk_size c then false
|
||||||
|
else verify pk msg signature (to_curve c)
|
||||||
|
|
||||||
|
(*---------------------------------------------------------------------------
|
||||||
|
Copyright (c) 2017 Vincent Bernardoff
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
---------------------------------------------------------------------------*)
|
112
vendors/ocaml-uecc/src/uecc.mli
vendored
Normal file
112
vendors/ocaml-uecc/src/uecc.mli
vendored
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
(*---------------------------------------------------------------------------
|
||||||
|
Copyright (c) 2017 Vincent Bernardoff. All rights reserved.
|
||||||
|
Distributed under the ISC license, see terms at the end of the file.
|
||||||
|
---------------------------------------------------------------------------*)
|
||||||
|
|
||||||
|
type secp160r1
|
||||||
|
type secp192r1
|
||||||
|
type secp224r1
|
||||||
|
type secp256r1
|
||||||
|
type secp256k1
|
||||||
|
(** Kinds of ECC curves. *)
|
||||||
|
|
||||||
|
type _ t
|
||||||
|
(** Type of an ECC curve, parametrized by its kind. *)
|
||||||
|
|
||||||
|
val secp160r1 : secp160r1 t
|
||||||
|
val secp192r1 : secp192r1 t
|
||||||
|
val secp224r1 : secp224r1 t
|
||||||
|
val secp256r1 : secp256r1 t
|
||||||
|
val secp256k1 : secp256k1 t
|
||||||
|
(** Supported curves. *)
|
||||||
|
|
||||||
|
val sk_size : _ t -> int
|
||||||
|
(** [sk_size curve] is the size in bytes of secret keys from
|
||||||
|
[curve]. Typically the same as the curve size, (i.e. 32 bytes for
|
||||||
|
[secp256r1]) except for [secp160r1] which is 21 bytes. *)
|
||||||
|
|
||||||
|
val pk_size : _ t -> int
|
||||||
|
(** [pk_size curve] is the size in bytes of public keys from
|
||||||
|
[curve]. Equals to [2*curve_size]. *)
|
||||||
|
|
||||||
|
val compressed_size : _ t -> int
|
||||||
|
(** [compressed_size curve] is the size in bytes of compressed public
|
||||||
|
keys from [curve]. Equals to [pk_size curve/2+1]. *)
|
||||||
|
|
||||||
|
type secret
|
||||||
|
type public
|
||||||
|
type (_, _) key
|
||||||
|
(** Type of a key, parametrized by its curve and kind. *)
|
||||||
|
|
||||||
|
val equal : ('a, 'b) key -> ('a, 'b) key -> bool
|
||||||
|
(** [equal k1 k2] is [true] if [k1] is represented by the same bytes
|
||||||
|
as [k2], and [false] otherwise. *)
|
||||||
|
|
||||||
|
val neuterize : ('a, _) key -> ('a, public) key
|
||||||
|
(** [neuterize k] is [k] if [k] is public, or is the associated public
|
||||||
|
key of [k] if [k] is secret. *)
|
||||||
|
|
||||||
|
val sk_of_bytes :
|
||||||
|
'a t -> Bigstring.t -> (('a, secret) key * ('a, public) key) option
|
||||||
|
(** [sk_of_bytes curve buf] is [Some (sk, pk)] if [buf] contains a
|
||||||
|
valid serialization of a [curve] secret key, or [None] otherwise. *)
|
||||||
|
|
||||||
|
val pk_of_bytes : 'a t -> Bigstring.t -> ('a, public) key option
|
||||||
|
(** [pk_of_bytes curve buf] is [Some pk] if [buf] contains a valid
|
||||||
|
serialization of a [curve] public key, or [None] otherwise. *)
|
||||||
|
|
||||||
|
val to_bytes : ?compress:bool -> (_, _) key -> Bigstring.t
|
||||||
|
(** [to_bytes ?compress k] is a serialization of [k]. If [compress] is
|
||||||
|
[true] (the default) and [k] is a public key, the public key will
|
||||||
|
be in compressed format. *)
|
||||||
|
|
||||||
|
val write_key : ?compress:bool -> Bigstring.t -> (_, _) key -> int
|
||||||
|
(** [write_key buf k] writes [k] at [buf] and returns the number of
|
||||||
|
bytes actually written. *)
|
||||||
|
|
||||||
|
val keypair : 'a t -> (('a, secret) key * ('a, public) key) option
|
||||||
|
(** [keypair curve] is [Some (sk, pk)] where [sk] and [pk] is freshly
|
||||||
|
generated keypair for [curve] if everything went well, or [None]
|
||||||
|
otherwise. *)
|
||||||
|
|
||||||
|
val dh : ('a, secret) key -> ('a, public) key -> Bigstring.t option
|
||||||
|
(** [dh sk pk] is [Some buf] where [buf] contains a shared secret
|
||||||
|
value computed from your [sk] and someone else's [pk] if everything
|
||||||
|
went well, or [None] otherwise. *)
|
||||||
|
|
||||||
|
val write_dh : ('a, secret) key -> ('a, public) key -> Bigstring.t -> int
|
||||||
|
(** [write_dh sk pk buf] writes a shared secret value computed from your
|
||||||
|
[sk] and someone else's [pk] and returns the number of bytes
|
||||||
|
actually written (0 in the case of an error). *)
|
||||||
|
|
||||||
|
val sign : (_, secret) key -> Bigstring.t -> Bigstring.t option
|
||||||
|
(** [sign sk msg] is [Some signature] where [signature] is a valid
|
||||||
|
signature of [msg] with secret key [sk], or [None] if an error
|
||||||
|
occured. *)
|
||||||
|
|
||||||
|
val write_sign :
|
||||||
|
(_, secret) key -> Bigstring.t -> msg:Bigstring.t -> int
|
||||||
|
(** [write_sign sk ~msg buf] writes a signature of [msg] with [sk] to
|
||||||
|
[buf], and returns the number of bytes written (0 in the case of an
|
||||||
|
error). *)
|
||||||
|
|
||||||
|
val verify :
|
||||||
|
(_, public) key -> msg:Bigstring.t -> signature:Bigstring.t -> bool
|
||||||
|
(** [verify pk ~msg ~signature] is [true] if [signature] is a valid
|
||||||
|
signature of [msg] corresponding to [pk]. *)
|
||||||
|
|
||||||
|
(*---------------------------------------------------------------------------
|
||||||
|
Copyright (c) 2017 Vincent Bernardoff
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
---------------------------------------------------------------------------*)
|
142
vendors/ocaml-uecc/src/uecc_stubs.c
vendored
Normal file
142
vendors/ocaml-uecc/src/uecc_stubs.c
vendored
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
/* --------------------------------------------------------------------------
|
||||||
|
Copyright (c) 2017 Vincent Bernardoff. All rights reserved.
|
||||||
|
Distributed under the ISC license, see terms at the end of the file.
|
||||||
|
--------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#include <caml/mlvalues.h>
|
||||||
|
#include <caml/memory.h>
|
||||||
|
#include <caml/alloc.h>
|
||||||
|
#include <caml/custom.h>
|
||||||
|
#include <caml/bigarray.h>
|
||||||
|
#include "uECC.h"
|
||||||
|
|
||||||
|
#define Curve_val(v) (*((uECC_Curve *) Data_custom_val(v)))
|
||||||
|
|
||||||
|
#define Gen_custom_block(SNAME, CNAME, MNAME) \
|
||||||
|
static int compare_##SNAME(value a, value b) { \
|
||||||
|
CNAME aa = MNAME(a), bb = MNAME(b); \
|
||||||
|
return (aa == bb ? 0 : (aa < bb ? -1 : 1)); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
static struct custom_operations uecc_##SNAME##_ops = { \
|
||||||
|
.identifier = "uecc_" #SNAME, \
|
||||||
|
.finalize = custom_finalize_default, \
|
||||||
|
.compare = compare_##SNAME, \
|
||||||
|
.compare_ext = custom_compare_ext_default, \
|
||||||
|
.hash = custom_hash_default, \
|
||||||
|
.serialize = custom_serialize_default, \
|
||||||
|
.deserialize = custom_deserialize_default \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
static value alloc_##SNAME (CNAME a) { \
|
||||||
|
value custom = alloc_custom(&uecc_##SNAME##_ops, sizeof(CNAME), 0, 1); \
|
||||||
|
MNAME(custom) = a; \
|
||||||
|
return custom; \
|
||||||
|
}
|
||||||
|
|
||||||
|
Gen_custom_block(curve, uECC_Curve, Curve_val)
|
||||||
|
|
||||||
|
CAMLprim value uECC_curve_stub(value kind) {
|
||||||
|
CAMLparam1(kind);
|
||||||
|
CAMLlocal1(ret);
|
||||||
|
|
||||||
|
uECC_Curve c;
|
||||||
|
switch(Int_val(kind)) {
|
||||||
|
case 0:
|
||||||
|
c = uECC_secp160r1();
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
c = uECC_secp192r1();
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
c = uECC_secp224r1();
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
c = uECC_secp256r1();
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
c = uECC_secp256k1();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = alloc_curve(c);
|
||||||
|
CAMLreturn(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
CAMLprim value uECC_curve_private_key_size_stub(value curve) {
|
||||||
|
return Val_int(uECC_curve_private_key_size(Curve_val(curve)));
|
||||||
|
}
|
||||||
|
|
||||||
|
CAMLprim value uECC_curve_public_key_size_stub(value curve) {
|
||||||
|
return Val_int(uECC_curve_public_key_size(Curve_val(curve)));
|
||||||
|
}
|
||||||
|
|
||||||
|
CAMLprim value uECC_make_key_stub(value pk, value sk, value curve) {
|
||||||
|
return Val_bool(uECC_make_key(Caml_ba_data_val(pk),
|
||||||
|
Caml_ba_data_val(sk),
|
||||||
|
Curve_val(curve)));
|
||||||
|
}
|
||||||
|
|
||||||
|
CAMLprim value uECC_valid_public_key_stub(value pk, value curve) {
|
||||||
|
return Val_bool(uECC_valid_public_key(Caml_ba_data_val(pk),
|
||||||
|
Curve_val(curve)));
|
||||||
|
}
|
||||||
|
|
||||||
|
CAMLprim value uECC_compute_public_key_stub(value sk, value pk, value curve) {
|
||||||
|
return Val_bool(uECC_compute_public_key(Caml_ba_data_val(sk),
|
||||||
|
Caml_ba_data_val(pk),
|
||||||
|
Curve_val(curve)));
|
||||||
|
}
|
||||||
|
|
||||||
|
CAMLprim value uECC_compress_stub(value pk, value cpk, value curve) {
|
||||||
|
uECC_compress(Caml_ba_data_val(pk),
|
||||||
|
Caml_ba_data_val(cpk),
|
||||||
|
Curve_val(curve));
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
CAMLprim value uECC_decompress_stub(value cpk, value pk, value curve) {
|
||||||
|
uECC_decompress(Caml_ba_data_val(cpk),
|
||||||
|
Caml_ba_data_val(pk),
|
||||||
|
Curve_val(curve));
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
CAMLprim value uECC_shared_secret_stub(value pk, value sk, value secret, value curve) {
|
||||||
|
return Val_bool(uECC_shared_secret(Caml_ba_data_val(pk),
|
||||||
|
Caml_ba_data_val(sk),
|
||||||
|
Caml_ba_data_val(secret),
|
||||||
|
Curve_val(curve)));
|
||||||
|
}
|
||||||
|
|
||||||
|
CAMLprim value uECC_sign_stub(value sk, value msg, value signature, value curve) {
|
||||||
|
return Val_bool(uECC_sign(Caml_ba_data_val(sk),
|
||||||
|
Caml_ba_data_val(msg),
|
||||||
|
Caml_ba_array_val(msg)->dim[0],
|
||||||
|
Caml_ba_data_val(signature),
|
||||||
|
Curve_val(curve)));
|
||||||
|
}
|
||||||
|
|
||||||
|
CAMLprim value uECC_verify_stub(value pk, value msg, value signature, value curve) {
|
||||||
|
return Val_bool(uECC_verify(Caml_ba_data_val(pk),
|
||||||
|
Caml_ba_data_val(msg),
|
||||||
|
Caml_ba_array_val(msg)->dim[0],
|
||||||
|
Caml_ba_data_val(signature),
|
||||||
|
Curve_val(curve)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------
|
||||||
|
Copyright (c) 2017 Vincent Bernardoff
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
--------------------------------------------------------------------------- */
|
15
vendors/ocaml-uecc/test/jbuild
vendored
Normal file
15
vendors/ocaml-uecc/test/jbuild
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
(jbuild_version 1)
|
||||||
|
|
||||||
|
(executable
|
||||||
|
((name test)
|
||||||
|
(public_name test-uecc)
|
||||||
|
(libraries (alcotest uecc))))
|
||||||
|
|
||||||
|
(alias
|
||||||
|
((name runtest-uecc)
|
||||||
|
(deps (test.exe))
|
||||||
|
(action (run ${<}))))
|
||||||
|
|
||||||
|
(alias
|
||||||
|
((name runtest)
|
||||||
|
(deps ((alias runtest-uecc)))))
|
173
vendors/ocaml-uecc/test/test.ml
vendored
Normal file
173
vendors/ocaml-uecc/test/test.ml
vendored
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
open Alcotest
|
||||||
|
open Uecc
|
||||||
|
|
||||||
|
let nb_iterations = 10
|
||||||
|
|
||||||
|
let checki = check int
|
||||||
|
|
||||||
|
let test_sksize () =
|
||||||
|
checki __LOC__ 21 (sk_size secp160r1) ;
|
||||||
|
checki __LOC__ 24 (sk_size secp192r1) ;
|
||||||
|
checki __LOC__ 28 (sk_size secp224r1) ;
|
||||||
|
checki __LOC__ 32 (sk_size secp256r1) ;
|
||||||
|
checki __LOC__ 32 (sk_size secp256k1) ;
|
||||||
|
()
|
||||||
|
|
||||||
|
let test_pksize () =
|
||||||
|
checki __LOC__ 40 (pk_size secp160r1) ;
|
||||||
|
checki __LOC__ 48 (pk_size secp192r1) ;
|
||||||
|
checki __LOC__ 56 (pk_size secp224r1) ;
|
||||||
|
checki __LOC__ 64 (pk_size secp256r1) ;
|
||||||
|
checki __LOC__ 64 (pk_size secp256k1) ;
|
||||||
|
()
|
||||||
|
|
||||||
|
let test_export_curve curve =
|
||||||
|
match keypair curve with
|
||||||
|
| None -> assert false
|
||||||
|
| Some (sk, pk) ->
|
||||||
|
let sk_bytes = to_bytes ~compress:false sk in
|
||||||
|
let pk_bytes = to_bytes ~compress:false pk in
|
||||||
|
checki __LOC__ (sk_size curve) (Bigstring.length sk_bytes) ;
|
||||||
|
checki __LOC__ (pk_size curve + 1) (Bigstring.length pk_bytes) ;
|
||||||
|
match sk_of_bytes curve sk_bytes,
|
||||||
|
pk_of_bytes curve pk_bytes with
|
||||||
|
| Some (sk', pk'), Some pk'' ->
|
||||||
|
assert (equal sk sk') ;
|
||||||
|
assert (equal pk pk') ;
|
||||||
|
assert (equal pk pk'') ;
|
||||||
|
assert (equal pk' pk') ;
|
||||||
|
| _ -> assert false
|
||||||
|
|
||||||
|
let test_export_curve curve =
|
||||||
|
for _i = 0 to nb_iterations - 1 do
|
||||||
|
test_export_curve curve
|
||||||
|
done
|
||||||
|
|
||||||
|
let test_export () =
|
||||||
|
test_export_curve secp160r1 ;
|
||||||
|
test_export_curve secp192r1 ;
|
||||||
|
test_export_curve secp224r1 ;
|
||||||
|
test_export_curve secp256r1 ;
|
||||||
|
test_export_curve secp256k1 ;
|
||||||
|
()
|
||||||
|
|
||||||
|
let test_export_curve_compressed curve =
|
||||||
|
match keypair curve with
|
||||||
|
| None -> assert false
|
||||||
|
| Some (sk, pk) ->
|
||||||
|
let sk_bytes = to_bytes sk in
|
||||||
|
let pk_bytes = to_bytes pk in
|
||||||
|
checki __LOC__ (sk_size curve) (Bigstring.length sk_bytes) ;
|
||||||
|
checki __LOC__ (compressed_size curve) (Bigstring.length pk_bytes) ;
|
||||||
|
match sk_of_bytes curve sk_bytes,
|
||||||
|
pk_of_bytes curve pk_bytes with
|
||||||
|
| Some (sk', pk'), Some pk'' ->
|
||||||
|
assert (equal sk sk') ;
|
||||||
|
assert (equal pk pk') ;
|
||||||
|
assert (equal pk pk'') ;
|
||||||
|
assert (equal pk' pk') ;
|
||||||
|
| _ -> assert false
|
||||||
|
|
||||||
|
let test_export_curve_compressed curve =
|
||||||
|
for _i = 0 to nb_iterations - 1 do
|
||||||
|
test_export_curve_compressed curve
|
||||||
|
done
|
||||||
|
|
||||||
|
let test_export_compressed () =
|
||||||
|
test_export_curve_compressed secp160r1 ;
|
||||||
|
test_export_curve_compressed secp192r1 ;
|
||||||
|
test_export_curve_compressed secp224r1 ;
|
||||||
|
test_export_curve_compressed secp256r1 ;
|
||||||
|
test_export_curve_compressed secp256k1 ;
|
||||||
|
()
|
||||||
|
|
||||||
|
let test_keypair_curve curve =
|
||||||
|
match keypair curve with
|
||||||
|
| None -> assert false
|
||||||
|
| Some (sk, pk) ->
|
||||||
|
assert (equal sk sk) ;
|
||||||
|
assert (equal pk pk) ;
|
||||||
|
let pk' = neuterize sk in
|
||||||
|
assert (equal pk pk')
|
||||||
|
|
||||||
|
let test_keypair_curve curve =
|
||||||
|
for _i = 0 to nb_iterations - 1 do
|
||||||
|
test_keypair_curve curve
|
||||||
|
done
|
||||||
|
|
||||||
|
let test_keypair () =
|
||||||
|
test_keypair_curve secp160r1 ;
|
||||||
|
test_keypair_curve secp192r1 ;
|
||||||
|
test_keypair_curve secp224r1 ;
|
||||||
|
test_keypair_curve secp256r1 ;
|
||||||
|
test_keypair_curve secp256k1 ;
|
||||||
|
()
|
||||||
|
|
||||||
|
let test_dh_curve curve =
|
||||||
|
match keypair curve, keypair curve with
|
||||||
|
| Some (sk, pk), Some (sk', pk') ->
|
||||||
|
begin match dh sk pk', dh sk' pk with
|
||||||
|
| Some secret, Some secret' ->
|
||||||
|
assert (Bigstring.equal secret secret')
|
||||||
|
| _ -> assert false
|
||||||
|
end
|
||||||
|
| _ -> assert false
|
||||||
|
|
||||||
|
let test_dh_curve curve =
|
||||||
|
for _i = 0 to nb_iterations - 1 do
|
||||||
|
test_dh_curve curve
|
||||||
|
done
|
||||||
|
|
||||||
|
let test_dh () =
|
||||||
|
test_dh_curve secp160r1 ;
|
||||||
|
test_dh_curve secp192r1 ;
|
||||||
|
test_dh_curve secp224r1 ;
|
||||||
|
test_dh_curve secp256r1 ;
|
||||||
|
test_dh_curve secp256k1 ;
|
||||||
|
()
|
||||||
|
|
||||||
|
let msg =
|
||||||
|
Bigstring.of_string "Voulez-vous coucher avec moi, ce soir ?"
|
||||||
|
|
||||||
|
let test_sign_curve curve =
|
||||||
|
match keypair curve with
|
||||||
|
| None -> assert false
|
||||||
|
| Some (sk, pk) ->
|
||||||
|
let signature = Bigstring.create (pk_size curve) in
|
||||||
|
begin match write_sign sk signature ~msg with
|
||||||
|
| nb_written when nb_written = (pk_size curve) ->
|
||||||
|
assert (verify pk ~msg ~signature)
|
||||||
|
| _ -> assert false
|
||||||
|
end ;
|
||||||
|
match sign sk msg with
|
||||||
|
| None -> assert false
|
||||||
|
| Some signature ->
|
||||||
|
assert (verify pk ~msg ~signature)
|
||||||
|
|
||||||
|
let test_sign_curve curve =
|
||||||
|
for _i = 0 to nb_iterations - 1 do
|
||||||
|
test_sign_curve curve
|
||||||
|
done
|
||||||
|
|
||||||
|
let test_sign () =
|
||||||
|
test_sign_curve secp160r1 ;
|
||||||
|
test_sign_curve secp192r1 ;
|
||||||
|
test_sign_curve secp224r1 ;
|
||||||
|
test_sign_curve secp256r1 ;
|
||||||
|
test_sign_curve secp256k1 ;
|
||||||
|
()
|
||||||
|
|
||||||
|
let basic = [
|
||||||
|
"sksize", `Quick, test_sksize ;
|
||||||
|
"pksize", `Quick, test_pksize ;
|
||||||
|
"export", `Quick, test_export ;
|
||||||
|
"export_compressed", `Quick, test_export_compressed ;
|
||||||
|
"keypair", `Quick, test_keypair ;
|
||||||
|
"dh", `Quick, test_dh ;
|
||||||
|
"sign", `Quick, test_sign ;
|
||||||
|
]
|
||||||
|
|
||||||
|
let () =
|
||||||
|
Alcotest.run "uecc" [
|
||||||
|
"basic", basic ;
|
||||||
|
]
|
21
vendors/ocaml-uecc/uecc.opam
vendored
Normal file
21
vendors/ocaml-uecc/uecc.opam
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
opam-version: "1.2"
|
||||||
|
name: "uecc"
|
||||||
|
version: "1.0"
|
||||||
|
authors: "Vincent Bernardoff <vb@luminar.eu.org>"
|
||||||
|
maintainer: "Vincent Bernardoff <vb@luminar.eu.org>"
|
||||||
|
license: "ISC"
|
||||||
|
homepage: "https://github.com/vbmithr/ocaml-uecc"
|
||||||
|
bug-reports: "https://github.com/vbmithr/ocaml-uecc/issues"
|
||||||
|
dev-repo: "git://github.com/vbmithr/ocaml-uecc"
|
||||||
|
|
||||||
|
available: [
|
||||||
|
ocaml-version >= "4.02.0"
|
||||||
|
]
|
||||||
|
|
||||||
|
build: [ "jbuilder" "build" "-j" jobs "-p" name "@install" ]
|
||||||
|
build-test: [ "jbuilder" "runtest" "-p" name "-j" jobs ]
|
||||||
|
depends: [
|
||||||
|
"jbuilder" {build & >= "1.0+beta19.1"}
|
||||||
|
"bigstring" {>= "0.1.1"}
|
||||||
|
"alcotest" {test & >= "0.8.1"}
|
||||||
|
]
|
Loading…
Reference in New Issue
Block a user