New implementation of Curve25519 (using multiplications of words of 15 bits or so, should be much faster on Cortex M0).
This commit is contained in:
parent
2f9c953af4
commit
693d2a0085
6 changed files with 1574 additions and 7 deletions
5
Makefile
5
Makefile
|
|
@ -47,7 +47,7 @@ TESTX509 = testx509
|
||||||
TESTMATH = testmath
|
TESTMATH = testmath
|
||||||
|
|
||||||
OBJCODEC = $(BUILD)/ccopy.o $(BUILD)/dec16be.o $(BUILD)/dec16le.o $(BUILD)/dec32be.o $(BUILD)/dec32le.o $(BUILD)/dec64be.o $(BUILD)/dec64le.o $(BUILD)/enc16be.o $(BUILD)/enc16le.o $(BUILD)/enc32be.o $(BUILD)/enc32le.o $(BUILD)/enc64be.o $(BUILD)/enc64le.o $(BUILD)/pemdec.o
|
OBJCODEC = $(BUILD)/ccopy.o $(BUILD)/dec16be.o $(BUILD)/dec16le.o $(BUILD)/dec32be.o $(BUILD)/dec32le.o $(BUILD)/dec64be.o $(BUILD)/dec64le.o $(BUILD)/enc16be.o $(BUILD)/enc16le.o $(BUILD)/enc32be.o $(BUILD)/enc32le.o $(BUILD)/enc64be.o $(BUILD)/enc64le.o $(BUILD)/pemdec.o
|
||||||
OBJEC = $(BUILD)/ec_c25519_i15.o $(BUILD)/ec_curve25519.o $(BUILD)/ec_p256_m15.o $(BUILD)/ec_prime_i15.o $(BUILD)/ec_prime_i31.o $(BUILD)/ec_secp256r1.o $(BUILD)/ec_secp384r1.o $(BUILD)/ec_secp521r1.o $(BUILD)/ecdsa_atr.o $(BUILD)/ecdsa_i15_bits.o $(BUILD)/ecdsa_i15_sign_asn1.o $(BUILD)/ecdsa_i15_sign_raw.o $(BUILD)/ecdsa_i15_vrfy_asn1.o $(BUILD)/ecdsa_i15_vrfy_raw.o $(BUILD)/ecdsa_i31_bits.o $(BUILD)/ecdsa_i31_sign_asn1.o $(BUILD)/ecdsa_i31_sign_raw.o $(BUILD)/ecdsa_i31_vrfy_asn1.o $(BUILD)/ecdsa_i31_vrfy_raw.o $(BUILD)/ecdsa_rta.o
|
OBJEC = $(BUILD)/ec_c25519_i15.o $(BUILD)/ec_c25519_m15.o $(BUILD)/ec_curve25519.o $(BUILD)/ec_p256_m15.o $(BUILD)/ec_prime_i15.o $(BUILD)/ec_prime_i31.o $(BUILD)/ec_secp256r1.o $(BUILD)/ec_secp384r1.o $(BUILD)/ec_secp521r1.o $(BUILD)/ecdsa_atr.o $(BUILD)/ecdsa_i15_bits.o $(BUILD)/ecdsa_i15_sign_asn1.o $(BUILD)/ecdsa_i15_sign_raw.o $(BUILD)/ecdsa_i15_vrfy_asn1.o $(BUILD)/ecdsa_i15_vrfy_raw.o $(BUILD)/ecdsa_i31_bits.o $(BUILD)/ecdsa_i31_sign_asn1.o $(BUILD)/ecdsa_i31_sign_raw.o $(BUILD)/ecdsa_i31_vrfy_asn1.o $(BUILD)/ecdsa_i31_vrfy_raw.o $(BUILD)/ecdsa_rta.o
|
||||||
# $(BUILD)/ec_prime_i31_secp256r1.o $(BUILD)/ec_prime_i31_secp384r1.o $(BUILD)/ec_prime_i31_secp521r1.o
|
# $(BUILD)/ec_prime_i31_secp256r1.o $(BUILD)/ec_prime_i31_secp384r1.o $(BUILD)/ec_prime_i31_secp521r1.o
|
||||||
OBJHASH = $(BUILD)/dig_oid.o $(BUILD)/dig_size.o $(BUILD)/ghash_ctmul.o $(BUILD)/ghash_ctmul32.o $(BUILD)/ghash_ctmul64.o $(BUILD)/md5.o $(BUILD)/md5sha1.o $(BUILD)/multihash.o $(BUILD)/sha1.o $(BUILD)/sha2big.o $(BUILD)/sha2small.o
|
OBJHASH = $(BUILD)/dig_oid.o $(BUILD)/dig_size.o $(BUILD)/ghash_ctmul.o $(BUILD)/ghash_ctmul32.o $(BUILD)/ghash_ctmul64.o $(BUILD)/md5.o $(BUILD)/md5sha1.o $(BUILD)/multihash.o $(BUILD)/sha1.o $(BUILD)/sha2big.o $(BUILD)/sha2small.o
|
||||||
OBJINT15 = $(BUILD)/i15_core.o $(BUILD)/i15_ext1.o $(BUILD)/i15_ext2.o
|
OBJINT15 = $(BUILD)/i15_core.o $(BUILD)/i15_ext1.o $(BUILD)/i15_ext2.o
|
||||||
|
|
@ -165,6 +165,9 @@ $(BUILD)/ec_g_secp521r1.o: src/ec/ec_g_secp521r1.c $(HEADERS)
|
||||||
$(BUILD)/ec_c25519_i15.o: src/ec/ec_c25519_i15.c $(HEADERS)
|
$(BUILD)/ec_c25519_i15.o: src/ec/ec_c25519_i15.c $(HEADERS)
|
||||||
$(CC) $(CFLAGS) -c -o $(BUILD)/ec_c25519_i15.o src/ec/ec_c25519_i15.c
|
$(CC) $(CFLAGS) -c -o $(BUILD)/ec_c25519_i15.o src/ec/ec_c25519_i15.c
|
||||||
|
|
||||||
|
$(BUILD)/ec_c25519_m15.o: src/ec/ec_c25519_m15.c $(HEADERS)
|
||||||
|
$(CC) $(CFLAGS) -c -o $(BUILD)/ec_c25519_m15.o src/ec/ec_c25519_m15.c
|
||||||
|
|
||||||
$(BUILD)/ec_curve25519.o: src/ec/ec_curve25519.c $(HEADERS)
|
$(BUILD)/ec_curve25519.o: src/ec/ec_curve25519.c $(HEADERS)
|
||||||
$(CC) $(CFLAGS) -c -o $(BUILD)/ec_curve25519.o src/ec/ec_curve25519.c
|
$(CC) $(CFLAGS) -c -o $(BUILD)/ec_curve25519.o src/ec/ec_curve25519.c
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -410,12 +410,12 @@ extern const br_ec_impl br_ec_prime_i31;
|
||||||
extern const br_ec_impl br_ec_prime_i15;
|
extern const br_ec_impl br_ec_prime_i15;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief EC implementation "i15" for P-256.
|
* \brief EC implementation "m15" for P-256.
|
||||||
*
|
*
|
||||||
* This implementation uses specialised code for curve secp256r1 (also
|
* This implementation uses specialised code for curve secp256r1 (also
|
||||||
* known as NIST P-256), with Karatsuba decomposition, and fast modular
|
* known as NIST P-256), with optional Karatsuba decomposition, and fast
|
||||||
* reduction thanks to the field modulus special format. Only 32-bit
|
* modular reduction thanks to the field modulus special format. Only
|
||||||
* multiplications are used (with 32-bit results, not 64-bit).
|
* 32-bit multiplications are used (with 32-bit results, not 64-bit).
|
||||||
*/
|
*/
|
||||||
extern const br_ec_impl br_ec_p256_m15;
|
extern const br_ec_impl br_ec_p256_m15;
|
||||||
|
|
||||||
|
|
@ -428,6 +428,14 @@ extern const br_ec_impl br_ec_p256_m15;
|
||||||
*/
|
*/
|
||||||
extern const br_ec_impl br_ec_c25519_i15;
|
extern const br_ec_impl br_ec_c25519_i15;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief EC implementation "m15" (specialised code) for Curve25519.
|
||||||
|
*
|
||||||
|
* This implementation uses custom code relying on multiplication of
|
||||||
|
* integers up to 15 bits. The `muladd()` method is not implemented.
|
||||||
|
*/
|
||||||
|
extern const br_ec_impl br_ec_c25519_m15;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Convert a signature from "raw" to "asn1".
|
* \brief Convert a signature from "raw" to "asn1".
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,27 @@ static const uint16_t C255_R2[] = {
|
||||||
0x0000
|
0x0000
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* obsolete
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
static void
|
||||||
|
print_int_mont(const char *name, const uint16_t *x)
|
||||||
|
{
|
||||||
|
uint16_t y[18];
|
||||||
|
unsigned char tmp[32];
|
||||||
|
size_t u;
|
||||||
|
|
||||||
|
printf("%s = ", name);
|
||||||
|
memcpy(y, x, sizeof y);
|
||||||
|
br_i15_from_monty(y, C255_P, P0I);
|
||||||
|
br_i15_encode(tmp, sizeof tmp, y);
|
||||||
|
for (u = 0; u < sizeof tmp; u ++) {
|
||||||
|
printf("%02X", tmp[u]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
static const uint16_t C255_A24[] = {
|
static const uint16_t C255_A24[] = {
|
||||||
0x0110,
|
0x0110,
|
||||||
0x45D3, 0x0046, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
0x45D3, 0x0046, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||||
|
|
@ -194,6 +215,10 @@ api_mul(unsigned char *G, size_t Glen,
|
||||||
k[31] &= 0x7F;
|
k[31] &= 0x7F;
|
||||||
k[31] |= 0x40;
|
k[31] |= 0x40;
|
||||||
|
|
||||||
|
/* obsolete
|
||||||
|
print_int_mont("x1", x1);
|
||||||
|
*/
|
||||||
|
|
||||||
swap = 0;
|
swap = 0;
|
||||||
for (i = 254; i >= 0; i --) {
|
for (i = 254; i >= 0; i --) {
|
||||||
uint32_t kt;
|
uint32_t kt;
|
||||||
|
|
@ -204,6 +229,13 @@ api_mul(unsigned char *G, size_t Glen,
|
||||||
cswap(z2, z3, swap);
|
cswap(z2, z3, swap);
|
||||||
swap = kt;
|
swap = kt;
|
||||||
|
|
||||||
|
/* obsolete
|
||||||
|
print_int_mont("x2", x2);
|
||||||
|
print_int_mont("z2", z2);
|
||||||
|
print_int_mont("x3", x3);
|
||||||
|
print_int_mont("z3", z3);
|
||||||
|
*/
|
||||||
|
|
||||||
c255_add(a, x2, z2);
|
c255_add(a, x2, z2);
|
||||||
c255_mul(aa, a, a);
|
c255_mul(aa, a, a);
|
||||||
c255_sub(b, x2, z2);
|
c255_sub(b, x2, z2);
|
||||||
|
|
@ -213,6 +245,19 @@ api_mul(unsigned char *G, size_t Glen,
|
||||||
c255_sub(d, x3, z3);
|
c255_sub(d, x3, z3);
|
||||||
c255_mul(da, d, a);
|
c255_mul(da, d, a);
|
||||||
c255_mul(cb, c, b);
|
c255_mul(cb, c, b);
|
||||||
|
|
||||||
|
/* obsolete
|
||||||
|
print_int_mont("a ", a);
|
||||||
|
print_int_mont("aa", aa);
|
||||||
|
print_int_mont("b ", b);
|
||||||
|
print_int_mont("bb", bb);
|
||||||
|
print_int_mont("e ", e);
|
||||||
|
print_int_mont("c ", c);
|
||||||
|
print_int_mont("d ", d);
|
||||||
|
print_int_mont("da", da);
|
||||||
|
print_int_mont("cb", cb);
|
||||||
|
*/
|
||||||
|
|
||||||
c255_add(x3, da, cb);
|
c255_add(x3, da, cb);
|
||||||
c255_mul(x3, x3, x3);
|
c255_mul(x3, x3, x3);
|
||||||
c255_sub(z3, da, cb);
|
c255_sub(z3, da, cb);
|
||||||
|
|
@ -222,6 +267,13 @@ api_mul(unsigned char *G, size_t Glen,
|
||||||
c255_mul(z2, C255_A24, e);
|
c255_mul(z2, C255_A24, e);
|
||||||
c255_add(z2, z2, aa);
|
c255_add(z2, z2, aa);
|
||||||
c255_mul(z2, e, z2);
|
c255_mul(z2, e, z2);
|
||||||
|
|
||||||
|
/* obsolete
|
||||||
|
print_int_mont("x2", x2);
|
||||||
|
print_int_mont("z2", z2);
|
||||||
|
print_int_mont("x3", x3);
|
||||||
|
print_int_mont("z3", z3);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
cswap(x2, x3, swap);
|
cswap(x2, x3, swap);
|
||||||
cswap(z2, z3, swap);
|
cswap(z2, z3, swap);
|
||||||
|
|
|
||||||
1451
src/ec/ec_c25519_m15.c
Normal file
1451
src/ec/ec_c25519_m15.c
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -4935,13 +4935,13 @@ const struct {
|
||||||
static void
|
static void
|
||||||
test_EC_c25519(const char *name, const br_ec_impl *iec)
|
test_EC_c25519(const char *name, const br_ec_impl *iec)
|
||||||
{
|
{
|
||||||
|
unsigned char bu[32], bk[32], br[32];
|
||||||
size_t v;
|
size_t v;
|
||||||
|
int i;
|
||||||
|
|
||||||
printf("Test %s: ", name);
|
printf("Test %s: ", name);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
for (v = 0; C25519_KAT[v].scalar; v ++) {
|
for (v = 0; C25519_KAT[v].scalar; v ++) {
|
||||||
unsigned char bu[32], bk[32], br[32];
|
|
||||||
|
|
||||||
hextobin(bk, C25519_KAT[v].scalar);
|
hextobin(bk, C25519_KAT[v].scalar);
|
||||||
hextobin(bu, C25519_KAT[v].u_in);
|
hextobin(bu, C25519_KAT[v].u_in);
|
||||||
hextobin(br, C25519_KAT[v].u_out);
|
hextobin(br, C25519_KAT[v].u_out);
|
||||||
|
|
@ -4956,6 +4956,44 @@ test_EC_c25519(const char *name, const br_ec_impl *iec)
|
||||||
printf(".");
|
printf(".");
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
|
printf(" ");
|
||||||
|
fflush(stdout);
|
||||||
|
|
||||||
|
memset(bu, 0, sizeof bu);
|
||||||
|
bu[0] = 0x09;
|
||||||
|
memcpy(bk, bu, sizeof bu);
|
||||||
|
for (i = 1; i <= 1000; i ++) {
|
||||||
|
if (!iec->mul(bu, sizeof bu, bk, sizeof bk, BR_EC_curve25519)) {
|
||||||
|
fprintf(stderr, "Curve25519 multiplication failed"
|
||||||
|
" (iter=%d)\n", i);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
for (v = 0; v < sizeof bu; v ++) {
|
||||||
|
unsigned t;
|
||||||
|
|
||||||
|
t = bu[v];
|
||||||
|
bu[v] = bk[v];
|
||||||
|
bk[v] = t;
|
||||||
|
}
|
||||||
|
if (i == 1 || i == 1000) {
|
||||||
|
const char *sref;
|
||||||
|
|
||||||
|
sref = (i == 1)
|
||||||
|
? "422C8E7A6227D7BCA1350B3E2BB7279F7897B87BB6854B783C60E80311AE3079"
|
||||||
|
: "684CF59BA83309552800EF566F2F4D3C1C3887C49360E3875F2EB94D99532C51";
|
||||||
|
hextobin(br, sref);
|
||||||
|
if (memcmp(bk, br, sizeof bk) != 0) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Curve25519 failed KAT (iter=%d)\n", i);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i % 100 == 0) {
|
||||||
|
printf(".");
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
printf(" done.\n");
|
printf(" done.\n");
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
|
|
@ -4966,6 +5004,12 @@ test_EC_c25519_i15(void)
|
||||||
test_EC_c25519("EC_c25519_i15", &br_ec_c25519_i15);
|
test_EC_c25519("EC_c25519_i15", &br_ec_c25519_i15);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_EC_c25519_m15(void)
|
||||||
|
{
|
||||||
|
test_EC_c25519("EC_c25519_m15", &br_ec_c25519_m15);
|
||||||
|
}
|
||||||
|
|
||||||
static const unsigned char EC_P256_PUB_POINT[] = {
|
static const unsigned char EC_P256_PUB_POINT[] = {
|
||||||
0x04, 0x60, 0xFE, 0xD4, 0xBA, 0x25, 0x5A, 0x9D,
|
0x04, 0x60, 0xFE, 0xD4, 0xBA, 0x25, 0x5A, 0x9D,
|
||||||
0x31, 0xC9, 0x61, 0xEB, 0x74, 0xC6, 0x35, 0x6D,
|
0x31, 0xC9, 0x61, 0xEB, 0x74, 0xC6, 0x35, 0x6D,
|
||||||
|
|
@ -5513,6 +5557,7 @@ static const struct {
|
||||||
STU(EC_p256_m15),
|
STU(EC_p256_m15),
|
||||||
/* STU(EC_prime_i32), */
|
/* STU(EC_prime_i32), */
|
||||||
STU(EC_c25519_i15),
|
STU(EC_c25519_i15),
|
||||||
|
STU(EC_c25519_m15),
|
||||||
STU(ECDSA_i15),
|
STU(ECDSA_i15),
|
||||||
STU(ECDSA_i31),
|
STU(ECDSA_i31),
|
||||||
{ 0, 0 }
|
{ 0, 0 }
|
||||||
|
|
|
||||||
|
|
@ -714,6 +714,13 @@ test_speed_ec_c25519_i15(void)
|
||||||
&br_ec_c25519_i15, &br_curve25519);
|
&br_ec_c25519_i15, &br_curve25519);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_speed_ec_c25519_m15(void)
|
||||||
|
{
|
||||||
|
test_speed_ec_inner("EC m15 C25519",
|
||||||
|
&br_ec_c25519_m15, &br_curve25519);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_speed_ecdsa_inner(const char *name,
|
test_speed_ecdsa_inner(const char *name,
|
||||||
const br_ec_impl *impl, const br_ec_curve_def *cd,
|
const br_ec_impl *impl, const br_ec_curve_def *cd,
|
||||||
|
|
@ -1256,6 +1263,7 @@ static const struct {
|
||||||
STU(ec_prime_i15),
|
STU(ec_prime_i15),
|
||||||
STU(ec_prime_i31),
|
STU(ec_prime_i31),
|
||||||
STU(ec_c25519_i15),
|
STU(ec_c25519_i15),
|
||||||
|
STU(ec_c25519_m15),
|
||||||
STU(ecdsa_p256_m15),
|
STU(ecdsa_p256_m15),
|
||||||
STU(ecdsa_i15),
|
STU(ecdsa_i15),
|
||||||
STU(ecdsa_i31),
|
STU(ecdsa_i31),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue