mirror of
https://github.com/neocturne/libuecc.git
synced 2025-03-04 09:03:31 +01:00
Reworked the API
This commit is contained in:
parent
f67c3f36b9
commit
bccf64ec1b
4 changed files with 96 additions and 58 deletions
|
@ -27,14 +27,14 @@
|
||||||
#ifndef _LIBUECC_ECC_H_
|
#ifndef _LIBUECC_ECC_H_
|
||||||
#define _LIBUECC_ECC_H_
|
#define _LIBUECC_ECC_H_
|
||||||
|
|
||||||
typedef struct _ecc_public_key_256 {
|
typedef union _ecc_int_256 {
|
||||||
unsigned char p[32];
|
unsigned char p[32];
|
||||||
} ecc_public_key_256;
|
|
||||||
|
|
||||||
typedef struct _ecc_secret_key_256 {
|
/* old name */
|
||||||
unsigned char s[32];
|
unsigned char s[32];
|
||||||
} ecc_secret_key_256;
|
} ecc_int_256, ecc_secret_key_256, ecc_public_key_256;
|
||||||
|
|
||||||
|
/* a point on the curve unpacked for efficient calculation */
|
||||||
typedef struct _ecc_25519_work {
|
typedef struct _ecc_25519_work {
|
||||||
unsigned int X[32];
|
unsigned int X[32];
|
||||||
unsigned int Y[32];
|
unsigned int Y[32];
|
||||||
|
@ -43,20 +43,36 @@ typedef struct _ecc_25519_work {
|
||||||
} ecc_25519_work;
|
} ecc_25519_work;
|
||||||
|
|
||||||
|
|
||||||
void ecc_25519_load(ecc_25519_work *out, const ecc_public_key_256 *in);
|
void ecc_25519_load_xy(ecc_25519_work *out, const ecc_int_256 *x, const ecc_int_256 *y);
|
||||||
void ecc_25519_store(ecc_public_key_256 *out, const ecc_25519_work *in);
|
void ecc_25519_store_xy(ecc_int_256 *x, ecc_int_256 *y, const ecc_25519_work *in);
|
||||||
|
|
||||||
|
void ecc_25519_load_packed(ecc_25519_work *out, const ecc_int_256 *in);
|
||||||
|
void ecc_25519_store_packed(ecc_int_256 *out, const ecc_25519_work *in);
|
||||||
|
|
||||||
int ecc_25519_is_identity(const ecc_25519_work *in);
|
int ecc_25519_is_identity(const ecc_25519_work *in);
|
||||||
void ecc_25519_add(ecc_25519_work *out, const ecc_25519_work *in1, const ecc_25519_work *in2);
|
void ecc_25519_add(ecc_25519_work *out, const ecc_25519_work *in1, const ecc_25519_work *in2);
|
||||||
void ecc_25519_double(ecc_25519_work *out, const ecc_25519_work *in);
|
void ecc_25519_double(ecc_25519_work *out, const ecc_25519_work *in);
|
||||||
void ecc_25519_scalarmult(ecc_25519_work *out, const ecc_secret_key_256 *n, const ecc_25519_work *base);
|
void ecc_25519_scalarmult(ecc_25519_work *out, const ecc_int_256 *n, const ecc_25519_work *base);
|
||||||
void ecc_25519_scalarmult_base(ecc_25519_work *out, const ecc_secret_key_256 *n);
|
void ecc_25519_scalarmult_base(ecc_25519_work *out, const ecc_int_256 *n);
|
||||||
|
|
||||||
int ecc_25519_secret_is_zero(const ecc_secret_key_256 *in);
|
/* operations on elements of the prime field F_q for q = 2^252 + 27742317777372353535851937790883648493 */
|
||||||
void ecc_25519_secret_add(ecc_secret_key_256 *out, const ecc_secret_key_256 *in1, const ecc_secret_key_256 *in2);
|
int ecc_25519_gf_is_zero(const ecc_int_256 *in);
|
||||||
void ecc_25519_secret_sub(ecc_secret_key_256 *out, const ecc_secret_key_256 *in1, const ecc_secret_key_256 *in2);
|
void ecc_25519_gf_add(ecc_int_256 *out, const ecc_int_256 *in1, const ecc_int_256 *in2);
|
||||||
void ecc_25519_secret_reduce(ecc_secret_key_256 *out, const ecc_secret_key_256 *in);
|
void ecc_25519_gf_sub(ecc_int_256 *out, const ecc_int_256 *in1, const ecc_int_256 *in2);
|
||||||
void ecc_25519_secret_mult(ecc_secret_key_256 *out, const ecc_secret_key_256 *in1, const ecc_secret_key_256 *in2);
|
void ecc_25519_gf_reduce(ecc_int_256 *out, const ecc_int_256 *in);
|
||||||
void ecc_25519_secret_sanitize(ecc_secret_key_256 *out, const ecc_secret_key_256 *in);
|
void ecc_25519_gf_mult(ecc_int_256 *out, const ecc_int_256 *in1, const ecc_int_256 *in2);
|
||||||
|
|
||||||
|
void ecc_25519_gf_sanitize_secret(ecc_int_256 *out, const ecc_int_256 *in);
|
||||||
|
|
||||||
|
/* defines for the old names */
|
||||||
|
#define ecc_25519_load ecc_25519_load_packed
|
||||||
|
#define ecc_25519_store ecc_25519_store_packed
|
||||||
|
|
||||||
|
#define ecc_25519_secret_is_zero ecc_25519_gf_is_zero
|
||||||
|
#define ecc_25519_secret_add ecc_25519_gf_add
|
||||||
|
#define ecc_25519_secret_sub ecc_25519_gf_sub
|
||||||
|
#define ecc_25519_secret_reduce ecc_25519_gf_reduce
|
||||||
|
#define ecc_25519_secret_mult ecc_25519_gf_mult
|
||||||
|
#define ecc_25519_secret_sanitize ecc_25519_gf_sanitize_secret
|
||||||
|
|
||||||
#endif /* _LIBUECC_ECC_H_ */
|
#endif /* _LIBUECC_ECC_H_ */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
include_directories(${LIBUECC_SOURCE_DIR}/include)
|
include_directories(${LIBUECC_SOURCE_DIR}/include)
|
||||||
|
|
||||||
add_library(uecc STATIC ec25519.c ec25519_secret.c)
|
add_library(uecc STATIC ec25519.c ec25519_gf.c)
|
||||||
|
|
||||||
install(TARGETS uecc
|
install(TARGETS uecc
|
||||||
ARCHIVE DESTINATION lib
|
ARCHIVE DESTINATION lib
|
||||||
|
|
|
@ -347,7 +347,40 @@ static void recip(unsigned int out[32], const unsigned int z[32]) {
|
||||||
/* 2^255 - 21 */ mult(out, t1, z11);
|
/* 2^255 - 21 */ mult(out, t1, z11);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ecc_25519_load(ecc_25519_work *out, const ecc_public_key_256 *in) {
|
void ecc_25519_load_xy(ecc_25519_work *out, const ecc_int_256 *x, const ecc_int_256 *y) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < 32; i++) {
|
||||||
|
out->X[i] = x->p[i];
|
||||||
|
out->Y[i] = y->p[i];
|
||||||
|
out->Z[i] = (i == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
mult(out->T, out->X, out->Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ecc_25519_store_xy(ecc_int_256 *x, ecc_int_256 *y, const ecc_25519_work *in) {
|
||||||
|
unsigned int X[32], Y[32], Z[32];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
recip(Z, in->Z);
|
||||||
|
|
||||||
|
if (x) {
|
||||||
|
mult(X, Z, in->X);
|
||||||
|
freeze(X);
|
||||||
|
for (i = 0; i < 32; i++)
|
||||||
|
x->p[i] = X[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y) {
|
||||||
|
mult(Y, Z, in->Y);
|
||||||
|
freeze(Y);
|
||||||
|
for (i = 0; i < 32; i++)
|
||||||
|
y->p[i] = Y[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ecc_25519_load_packed(ecc_25519_work *out, const ecc_int_256 *in) {
|
||||||
static const unsigned int zero[32] = {0};
|
static const unsigned int zero[32] = {0};
|
||||||
static const unsigned int one[32] = {1};
|
static const unsigned int one[32] = {1};
|
||||||
|
|
||||||
|
@ -377,22 +410,11 @@ void ecc_25519_load(ecc_25519_work *out, const ecc_public_key_256 *in) {
|
||||||
mult(out->T, out->X, out->Y);
|
mult(out->T, out->X, out->Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ecc_25519_store(ecc_public_key_256 *out, const ecc_25519_work *in) {
|
void ecc_25519_store_packed(ecc_int_256 *out, const ecc_25519_work *in) {
|
||||||
unsigned int x[32], y[32], z[32];
|
ecc_int_256 y;
|
||||||
int i;
|
|
||||||
|
|
||||||
recip(z, in->Z);
|
ecc_25519_store_xy(out, &y, in);
|
||||||
|
out->p[31] |= (y.p[0] << 7);
|
||||||
mult(x, z, in->X);
|
|
||||||
mult(y, z, in->Y);
|
|
||||||
|
|
||||||
freeze(x);
|
|
||||||
freeze(y);
|
|
||||||
|
|
||||||
for (i = 0; i < 32; i++)
|
|
||||||
out->p[i] = x[i];
|
|
||||||
|
|
||||||
out->p[31] |= (y[0] << 7);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const ecc_25519_work id = {{0}, {1}, {1}, {0}};
|
static const ecc_25519_work id = {{0}, {1}, {1}, {0}};
|
||||||
|
@ -450,13 +472,13 @@ void ecc_25519_add(ecc_25519_work *out, const ecc_25519_work *in1, const ecc_255
|
||||||
mult(out->Z, F, G);
|
mult(out->Z, F, G);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ecc_25519_scalarmult(ecc_25519_work *out, const ecc_secret_key_256 *n, const ecc_25519_work *base) {
|
void ecc_25519_scalarmult(ecc_25519_work *out, const ecc_int_256 *n, const ecc_25519_work *base) {
|
||||||
ecc_25519_work Q2, Q2p;
|
ecc_25519_work Q2, Q2p;
|
||||||
ecc_25519_work cur = id;
|
ecc_25519_work cur = id;
|
||||||
int b, pos;
|
int b, pos;
|
||||||
|
|
||||||
for (pos = 255; pos >= 0; --pos) {
|
for (pos = 255; pos >= 0; --pos) {
|
||||||
b = n->s[pos / 8] >> (pos & 7);
|
b = n->p[pos / 8] >> (pos & 7);
|
||||||
b &= 1;
|
b &= 1;
|
||||||
|
|
||||||
ecc_25519_double(&Q2, &cur);
|
ecc_25519_double(&Q2, &cur);
|
||||||
|
@ -483,6 +505,6 @@ static const ecc_25519_work default_base = {
|
||||||
0x47, 0x4b, 0x4c, 0x81, 0xa6, 0x02, 0xfd, 0x29}
|
0x47, 0x4b, 0x4c, 0x81, 0xa6, 0x02, 0xfd, 0x29}
|
||||||
};
|
};
|
||||||
|
|
||||||
void ecc_25519_scalarmult_base(ecc_25519_work *out, const ecc_secret_key_256 *n) {
|
void ecc_25519_scalarmult_base(ecc_25519_work *out, const ecc_int_256 *n) {
|
||||||
ecc_25519_scalarmult(out, n, &default_base);
|
ecc_25519_scalarmult(out, n, &default_base);
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,43 +57,43 @@ static void select(unsigned char out[32], const unsigned char r[32], const unsig
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int ecc_25519_secret_is_zero(const ecc_secret_key_256 *in) {
|
int ecc_25519_gf_is_zero(const ecc_int_256 *in) {
|
||||||
int i;
|
int i;
|
||||||
ecc_secret_key_256 r;
|
ecc_int_256 r;
|
||||||
unsigned int bits;
|
unsigned int bits;
|
||||||
|
|
||||||
ecc_25519_secret_reduce(&r, in);
|
ecc_25519_gf_reduce(&r, in);
|
||||||
|
|
||||||
for (i = 0; i < 32; i++)
|
for (i = 0; i < 32; i++)
|
||||||
bits |= r.s[i];
|
bits |= r.p[i];
|
||||||
|
|
||||||
return (((bits-1)>>8) & 1);
|
return (((bits-1)>>8) & 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ecc_25519_secret_add(ecc_secret_key_256 *out, const ecc_secret_key_256 *in1, const ecc_secret_key_256 *in2) {
|
void ecc_25519_gf_add(ecc_int_256 *out, const ecc_int_256 *in1, const ecc_int_256 *in2) {
|
||||||
unsigned int j;
|
unsigned int j;
|
||||||
unsigned int u;
|
unsigned int u;
|
||||||
int nq = 1 - (in1->s[31]>>4) - (in2->s[31]>>4);
|
int nq = 1 - (in1->p[31]>>4) - (in2->p[31]>>4);
|
||||||
|
|
||||||
u = 0;
|
u = 0;
|
||||||
for (j = 0; j < 32; ++j) {
|
for (j = 0; j < 32; ++j) {
|
||||||
u += in1->s[j] + in2->s[j] + nq*q[j];
|
u += in1->p[j] + in2->p[j] + nq*q[j];
|
||||||
|
|
||||||
out->s[j] = u;
|
out->p[j] = u;
|
||||||
u = ASR(u, 8);
|
u = ASR(u, 8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ecc_25519_secret_sub(ecc_secret_key_256 *out, const ecc_secret_key_256 *in1, const ecc_secret_key_256 *in2) {
|
void ecc_25519_gf_sub(ecc_int_256 *out, const ecc_int_256 *in1, const ecc_int_256 *in2) {
|
||||||
unsigned int j;
|
unsigned int j;
|
||||||
unsigned int u;
|
unsigned int u;
|
||||||
int nq = 8 - (in1->s[31]>>4) + (in2->s[31]>>4);
|
int nq = 8 - (in1->p[31]>>4) + (in2->p[31]>>4);
|
||||||
|
|
||||||
u = 0;
|
u = 0;
|
||||||
for (j = 0; j < 32; ++j) {
|
for (j = 0; j < 32; ++j) {
|
||||||
u += in1->s[j] - in2->s[j] + nq*q[j];
|
u += in1->p[j] - in2->p[j] + nq*q[j];
|
||||||
|
|
||||||
out->s[j] = u;
|
out->p[j] = u;
|
||||||
u = ASR(u, 8);
|
u = ASR(u, 8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -120,13 +120,13 @@ static void reduce(unsigned char a[32]) {
|
||||||
select(a, out1, out2, IS_NEGATIVE(u1));
|
select(a, out1, out2, IS_NEGATIVE(u1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ecc_25519_secret_reduce(ecc_secret_key_256 *out, const ecc_secret_key_256 *in) {
|
void ecc_25519_gf_reduce(ecc_int_256 *out, const ecc_int_256 *in) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < 32; i++)
|
for (i = 0; i < 32; i++)
|
||||||
out->s[i] = in->s[i];
|
out->p[i] = in->p[i];
|
||||||
|
|
||||||
reduce(out->s);
|
reduce(out->p);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Montgomery modular multiplication algorithm */
|
/* Montgomery modular multiplication algorithm */
|
||||||
|
@ -154,7 +154,7 @@ static void montgomery(unsigned char out[32], const unsigned char a[32], const u
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ecc_25519_secret_mult(ecc_secret_key_256 *out, const ecc_secret_key_256 *in1, const ecc_secret_key_256 *in2) {
|
void ecc_25519_gf_mult(ecc_int_256 *out, const ecc_int_256 *in1, const ecc_int_256 *in2) {
|
||||||
/* 2^512 mod q */
|
/* 2^512 mod q */
|
||||||
static const unsigned char C[32] = {
|
static const unsigned char C[32] = {
|
||||||
0x01, 0x0f, 0x9c, 0x44, 0xe3, 0x11, 0x06, 0xa4,
|
0x01, 0x0f, 0x9c, 0x44, 0xe3, 0x11, 0x06, 0xa4,
|
||||||
|
@ -168,21 +168,21 @@ void ecc_25519_secret_mult(ecc_secret_key_256 *out, const ecc_secret_key_256 *in
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
for (i = 0; i < 32; i++)
|
for (i = 0; i < 32; i++)
|
||||||
B[i] = in2->s[i];
|
B[i] = in2->p[i];
|
||||||
|
|
||||||
reduce(B);
|
reduce(B);
|
||||||
|
|
||||||
montgomery(R, in1->s, B);
|
montgomery(R, in1->p, B);
|
||||||
montgomery(out->s, R, C);
|
montgomery(out->p, R, C);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ecc_25519_secret_sanitize(ecc_secret_key_256 *out, const ecc_secret_key_256 *in) {
|
void ecc_25519_gf_sanitize_secret(ecc_int_256 *out, const ecc_int_256 *in) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < 32; i++)
|
for (i = 0; i < 32; i++)
|
||||||
out->s[i] = in->s[i];
|
out->p[i] = in->p[i];
|
||||||
|
|
||||||
out->s[0] &= 0xf8;
|
out->p[0] &= 0xf8;
|
||||||
out->s[31] &= 0x7f;
|
out->p[31] &= 0x7f;
|
||||||
out->s[31] |= 0x40;
|
out->p[31] |= 0x40;
|
||||||
}
|
}
|
Loading…
Add table
Reference in a new issue