Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize size of ed25519 #4146

Merged
merged 4 commits into from
Sep 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions crypto/ed25519-donna/ed25519-donna-basepoint-table.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "ed25519-donna.h"
#include "options.h"

#if !OPTIMIZE_SIZE_ED25519
/* multiples of the base point in packed {ysubx, xaddy, t2d} form */
const uint8_t ALIGN(16) ge25519_niels_base_multiples[256][96] = {
{0x3e,0x91,0x40,0xd7,0x05,0x39,0x10,0x9d,0xb3,0xbe,0x40,0xd1,0x05,0x9f,0x39,0xfd,0x09,0x8a,0x8f,0x68,0x34,0x84,0xc1,0xa5,0x67,0x12,0xf8,0x98,0x92,0x2f,0xfd,0x44,0x85,0x3b,0x8c,0xf5,0xc6,0x93,0xbc,0x2f,0x19,0x0e,0x8c,0xfb,0xc6,0x2d,0x93,0xcf,0xc2,0x42,0x3d,0x64,0x98,0x48,0x0b,0x27,0x65,0xba,0xd4,0x33,0x3a,0x9d,0xcf,0x07,0x59,0xbb,0x6f,0x4b,0x67,0x15,0xbd,0xdb,0xea,0xa5,0xa2,0xee,0x00,0x3f,0xe1,0x41,0xfa,0xc6,0x57,0xc9,0x1c,0x9d,0xd4,0xcd,0xca,0xec,0x16,0xaf,0x1f,0xbe,0x0e,0x4f},
Expand Down Expand Up @@ -259,3 +261,4 @@ const uint8_t ALIGN(16) ge25519_niels_base_multiples[256][96] = {
{0x33,0x3e,0xed,0x2e,0xb3,0x07,0x13,0x46,0xe7,0x81,0x55,0xa4,0x33,0x2f,0x04,0xae,0x66,0x03,0x5f,0x19,0xd3,0x49,0x44,0xc9,0x58,0x48,0x31,0x6c,0x8a,0x5d,0x7d,0x0b,0xb9,0xb0,0x10,0x5e,0xaa,0xaf,0x6a,0x2a,0xa9,0x1a,0x04,0xef,0x70,0xa3,0xf0,0x78,0x1f,0xd6,0x3a,0xaa,0x77,0xfb,0x3e,0x77,0xe1,0xd9,0x4b,0xa7,0xa2,0xa5,0xec,0x44,0x43,0xd5,0x95,0x7b,0x32,0x48,0xd4,0x25,0x1d,0x0f,0x34,0xa3,0x00,0x83,0xd3,0x70,0x2b,0xc5,0xe1,0x60,0x1c,0x53,0x1c,0xde,0xe4,0xe9,0x7d,0x2c,0x51,0x24,0x22,0x27},
{0x2e,0x34,0xc5,0x49,0xaf,0x92,0xbc,0x1a,0xd0,0xfa,0xe6,0xb2,0x11,0xd8,0xee,0xff,0x29,0x4e,0xc8,0xfc,0x8d,0x8c,0xa2,0xef,0x43,0xc5,0x4c,0xa4,0x18,0xdf,0xb5,0x11,0xfc,0x75,0xa9,0x42,0x8a,0xbb,0x7b,0xbf,0x58,0xa3,0xad,0x96,0x77,0x39,0x5c,0x8c,0x48,0xaa,0xed,0xcd,0x6f,0xc7,0x7f,0xe2,0xa6,0x20,0xbc,0xf6,0xd7,0x5f,0x73,0x19,0x66,0x42,0xc8,0x42,0xd0,0x90,0xab,0xe3,0x7e,0x54,0x19,0x7f,0x0f,0x8e,0x84,0xeb,0xb9,0x97,0xa4,0x65,0xd0,0xa1,0x03,0x25,0x5f,0x89,0xdf,0x91,0x11,0x91,0xef,0x0f}
};
#endif
4 changes: 4 additions & 0 deletions crypto/ed25519-donna/ed25519-donna-basepoint-table.h
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
#include "options.h"

#if !OPTIMIZE_SIZE_ED25519
/* multiples of the base point in packed {ysubx, xaddy, t2d} form */
extern const uint8_t ALIGN(16) ge25519_niels_base_multiples[256][96];
#endif
28 changes: 22 additions & 6 deletions crypto/ed25519-donna/ed25519-donna-impl-base.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <assert.h>
#include "ed25519-donna.h"
#include "memzero.h"
#include "options.h"

/* sqrt(x) is such an integer y that 0 <= y <= p - 1, y % 2 = 0, and y^2 = x (mod p). */
/* d = -121665 / 121666 */
Expand Down Expand Up @@ -102,22 +103,33 @@ void ge25519_nielsadd2_p1p1(ge25519_p1p1 *r, const ge25519 *p, const ge25519_nie
#endif

void ge25519_pnielsadd_p1p1(ge25519_p1p1 *r, const ge25519 *p, const ge25519_pniels *q, unsigned char signbit) {
const bignum25519 *qb = (const bignum25519 *)q;
bignum25519 *rb = (bignum25519 *)r;
bignum25519 q1, q2 = {0};
bignum25519 a = {0}, b = {0}, c = {0};

curve25519_sub(a, p->y, p->x);
curve25519_add(b, p->y, p->x);
curve25519_mul(a, a, qb[signbit]); /* ysubx for +, xaddy for - */
curve25519_mul(r->x, b, qb[signbit^1]); /* xaddy for +, ysubx for - */

// a = a * ysubx, r->x = b * xaddy for signbit = 0
// a = a * xaddy, r->x = b * ysubx for signbit = 1
curve25519_copy(q1, q->ysubx);
curve25519_copy(q2, q->xaddy);
curve25519_swap_conditional(q1, q2, signbit);
curve25519_mul(a, a, q1);
curve25519_mul(r->x, b, q2);

curve25519_add(r->y, r->x, a);
curve25519_sub(r->x, r->x, a);
curve25519_mul(c, p->t, q->t2d);
curve25519_mul(r->t, p->z, q->z);
curve25519_add_reduce(r->t, r->t, r->t);
curve25519_copy(r->z, r->t);
curve25519_add(rb[2+signbit], rb[2+signbit], c); /* z for +, t for - */
curve25519_sub(rb[2+(signbit^1)], rb[2+(signbit^1)], c); /* t for +, z for - */

// r->z = r->z + c, r->t = r->t - c for signbit == 0
// r->z = r->z - c, r->t = r->t + c for signbit == 1
curve25519_swap_conditional(r->z, r->t, signbit);
curve25519_add(r->z, r->z, c);
curve25519_sub(r->t, r->t, c);
curve25519_swap_conditional(r->z, r->t, signbit);
}

void ge25519_double_partial(ge25519 *r, const ge25519 *p) {
Expand Down Expand Up @@ -726,5 +738,9 @@ int ge25519_unpack_vartime(ge25519 *r, const unsigned char *s){
}

void ge25519_scalarmult_base_wrapper(ge25519 *r, const bignum256modm s){
#if OPTIMIZE_SIZE_ED25519
ge25519_scalarmult(r, &ge25519_basepoint, s);
#else
ge25519_scalarmult_base_niels(r, ge25519_niels_base_multiples, s);
#endif
}
10 changes: 5 additions & 5 deletions crypto/ed25519-donna/ed25519.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ ED25519_FN(ed25519_cosi_commit) (ed25519_secret_key nonce, ed25519_public_key co
contract256_modm(nonce, r);

/* R = rB */
ge25519_scalarmult_base_niels(&R, ge25519_niels_base_multiples, r);
ge25519_scalarmult_base_wrapper(&R, r);
memzero(&r, sizeof(r));
ge25519_pack(commitment, &R);
}
Expand Down Expand Up @@ -118,14 +118,14 @@ ED25519_FN(ed25519_sign_ext) (const unsigned char *m, size_t mlen, const ed25519
memzero(&hashr, sizeof(hashr));

/* R = rB */
ge25519_scalarmult_base_niels(&R, ge25519_niels_base_multiples, r);
ge25519_scalarmult_base_wrapper(&R, r);
ge25519_pack(RS, &R);

/* a = aExt[0..31] */
expand256_modm(a, secret_scalar, 32);

/* A = aB */
ge25519_scalarmult_base_niels(&A, ge25519_niels_base_multiples, a);
ge25519_scalarmult_base_wrapper(&A, a);
ge25519_pack(pk, &A);

/* S = H(R,A,m).. */
Expand Down Expand Up @@ -213,7 +213,7 @@ ed25519_publickey_ext(const ed25519_secret_key extsk, ed25519_public_key pk) {
expand256_modm(a, extsk, 32);

/* A = aB */
ge25519_scalarmult_base_niels(&A, ge25519_niels_base_multiples, a);
ge25519_scalarmult_base_wrapper(&A, a);
memzero(&a, sizeof(a));
ge25519_pack(pk, &A);
}
Expand Down Expand Up @@ -284,7 +284,7 @@ curve25519_scalarmult_basepoint(curve25519_key pk, const curve25519_key e) {
memzero(&ec, sizeof(ec));

/* scalar * basepoint */
ge25519_scalarmult_base_niels(&p, ge25519_niels_base_multiples, s);
ge25519_scalarmult_base_wrapper(&p, s);
memzero(&s, sizeof(s));

/* u = (y + z) / (z - y) */
Expand Down
4 changes: 2 additions & 2 deletions crypto/monero/xmr.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,15 +86,15 @@ void xmr_derive_public_key(ge25519 *r, const ge25519 *deriv, uint32_t idx,
ge25519 p2 = {0};

xmr_derivation_to_scalar(s, deriv, idx);
ge25519_scalarmult_base_niels(&p2, ge25519_niels_base_multiples, s);
ge25519_scalarmult_base_wrapper(&p2, s);
ge25519_add(r, base, &p2, 0);
}

void xmr_add_keys2(ge25519 *r, const bignum256modm a, const bignum256modm b,
const ge25519 *B) {
// aG + bB, G is basepoint
ge25519 aG = {0}, bB = {0};
ge25519_scalarmult_base_niels(&aG, ge25519_niels_base_multiples, a);
ge25519_scalarmult_base_wrapper(&aG, a);
ge25519_scalarmult(&bB, B, b);
ge25519_add(r, &aG, &bB, 0);
}
Expand Down
4 changes: 4 additions & 0 deletions crypto/options.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@
#define OPTIMIZE_SIZE_BLAKE2B OPTIMIZE_SIZE
#endif

#ifndef OPTIMIZE_SIZE_ED25519
#define OPTIMIZE_SIZE_ED25519 OPTIMIZE_SIZE
#endif

// use precomputed Curve Points (some scalar multiples of curve base point G)
#ifndef USE_PRECOMPUTED_CP
#define USE_PRECOMPUTED_CP 0
Expand Down
4 changes: 2 additions & 2 deletions crypto/tests/test_check_monero.h
Original file line number Diff line number Diff line change
Expand Up @@ -522,8 +522,8 @@ START_TEST(test_xmr_ge25519_ops) {
set256_modm(s3, 8);
set256_modm(s4, 2);

ge25519_scalarmult_base_niels(&a, ge25519_niels_base_multiples, s1);
ge25519_scalarmult_base_niels(&b, ge25519_niels_base_multiples, s2);
ge25519_scalarmult_base_wrapper(&a, s1);
ge25519_scalarmult_base_wrapper(&b, s2);
ge25519_scalarmult(&c, &a, s4);
ge25519_scalarmult(&c, &c, s4);
ge25519_scalarmult(&c, &c, s4);
Expand Down
Loading