From: Michael Schroeder Date: Tue, 19 May 2020 11:59:16 +0000 (+0200) Subject: Improve ed25519 a bit X-Git-Tag: 0.7.14~10 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2377205800bba3f371f415d6d794e6e244f01154;p=thirdparty%2Flibsolv.git Improve ed25519 a bit --- diff --git a/ext/solv_ed25519.h b/ext/solv_ed25519.h index b48c3413..1ad43d92 100644 --- a/ext/solv_ed25519.h +++ b/ext/solv_ed25519.h @@ -92,7 +92,8 @@ mped25519_mul(mp_t *target, mp_t *m1, mp_t *m2) tmp[i] = x; x >>= MP_T_BITS; } - if (tmp[MPED25519_LEN - 1] >= ed25519_q[MPED25519_LEN - 1]) + if (tmp[MPED25519_LEN - 1] > ed25519_q[MPED25519_LEN - 1] || + (tmp[MPED25519_LEN - 1] == ed25519_q[MPED25519_LEN - 1] && !mpisless(MPED25519_LEN - 1, tmp, ed25519_q))) mpsubmod(MPED25519_LEN, tmp, ed25519_q); mpcpy(MPED25519_LEN, target, tmp); } @@ -146,28 +147,6 @@ mped25519_recover_x(mp_t *x, mp_t *y, int sign) return 1; } -static void -mped25519_setfromle(int len, mp_t *out, const unsigned char *buf, int bufl, int highmask) -{ - unsigned char lebuf[64]; /* bufl must be <= 64 */ - int i; - for (i = 0; i < bufl; i++) - lebuf[bufl - 1 - i] = buf[i]; - lebuf[0] &= highmask; - mpsetfrombe(len, out, lebuf, bufl); -} - -static void -mped25519_modn_fromle(mp_t *out, const unsigned char *buf, int bufl) -{ - mp_t tmp[64 / MP_T_BYTES]; /* bufl must be <= 64 */ - mp_t tmp2[MPED25519_LEN]; - int len = (bufl + MP_T_BYTES - 1) / MP_T_BYTES; - mped25519_setfromle(len, tmp, buf, bufl, 0xff); - mpzero(MPED25519_LEN, out); - mpmul_add(MPED25519_LEN, out, ed25519_one, len, tmp, tmp2, ed25519_n); -} - /* see https://hyperelliptic.org/EFD/g1p/auto-twisted-projective.html */ /* M=7 add=6 */ static void @@ -318,6 +297,17 @@ mped25519_scmult2(mp_t *r_x, mp_t *r_y, mp_t *s1, mp_t *p1_x, mp_t * p1_y, mp_t return mpiszero(MPED25519_LEN, p_z) ? 0 : 1; } +static void +mped25519_setfromle(int len, mp_t *out, const unsigned char *buf, int bufl, int highmask) +{ + unsigned char lebuf[64]; /* bufl must be <= 64 */ + int i; + for (i = 0; i < bufl; i++) + lebuf[bufl - 1 - i] = buf[i]; + lebuf[0] &= highmask; + mpsetfrombe(len, out, lebuf, bufl); +} + static int mped25519(const unsigned char *pub, const unsigned char *sigr, const unsigned char *sigs, const unsigned char *data, unsigned int datal) { @@ -325,11 +315,13 @@ mped25519(const unsigned char *pub, const unsigned char *sigr, const unsigned ch int i; mp_t pub_x[MPED25519_LEN], pub_y[MPED25519_LEN]; mp_t h[MPED25519_LEN], s[MPED25519_LEN]; + mp_t h2[MPED25519_LEN* 2], htmp[MPED25519_LEN]; mp_t r_x[MPED25519_LEN], r_y[MPED25519_LEN]; Chksum *chk; - if ((sigs[31] & 0xe0) != 0) - return 0; + mped25519_setfromle(MPED25519_LEN, s, sigs, 32, 0xff); + if (!mpisless(MPED25519_LEN, s, ed25519_n)) + return 0; /* bad s */ /* uncompress pubkey, we invert the sign to get -pub */ mped25519_setfromle(MPED25519_LEN, pub_y, pub, 32, 0x7f); if (!mped25519_recover_x(pub_x, pub_y, pub[31] & 0x80 ? 0 : 1)) @@ -337,7 +329,7 @@ mped25519(const unsigned char *pub, const unsigned char *sigr, const unsigned ch #if 0 mped25519_ptdump(pub_x, pub_y, 0, "pub = "); #endif - /* calculate h and s */ + /* calculate h2 */ chk = solv_chksum_create(REPOKEY_TYPE_SHA512); if (!chk) return 0; @@ -345,8 +337,10 @@ mped25519(const unsigned char *pub, const unsigned char *sigr, const unsigned ch solv_chksum_add(chk, pub, 32); solv_chksum_add(chk, data, datal); solv_chksum_free(chk, hbuf); - mped25519_modn_fromle(h, hbuf, 64); - mped25519_modn_fromle(s, sigs, 32); + /* calculate h = h2 mod n */ + mped25519_setfromle(MPED25519_LEN * 2, h2, hbuf, 64, 0xff); + mpzero(MPED25519_LEN, h); + mpmul_add(MPED25519_LEN, h, ed25519_one, MPED25519_LEN * 2, h2, htmp, ed25519_n); #if 0 mped25519_mpdump(s, "s = ", 0); mped25519_mpdump(h, "h = ", 0); diff --git a/ext/solv_pgpvrfy.c b/ext/solv_pgpvrfy.c index e4be692d..3e1a5592 100644 --- a/ext/solv_pgpvrfy.c +++ b/ext/solv_pgpvrfy.c @@ -24,18 +24,18 @@ typedef unsigned long long mp2_t; #define MP_T_BITS (MP_T_BYTES * 8) -static inline void -mpzero(int len, mp_t *target) -{ - memset(target, 0, MP_T_BYTES * len); -} - static inline mp_t * mpnew(int len) { return solv_calloc(len, MP_T_BYTES); } +static inline void +mpzero(int len, mp_t *target) +{ + memset(target, 0, MP_T_BYTES * len); +} + static inline void mpcpy(int len, mp_t *target, mp_t *source) { @@ -55,6 +55,34 @@ mpsetfrombe(int len, mp_t *target, const unsigned char *buf, int bufl) target[i / MP_T_BYTES] |= (int)(*--buf) << (8 * (i % MP_T_BYTES)); } +static int +mpisless(int len, mp_t *a, mp_t *b) +{ + int i; + for (i = len - 1; i >= 0; i--) + if (a[i] < b[i]) + return 1; + else if (a[i] > b[i]) + return 0; + return 0; +} + +static int +mpisequal(int len, mp_t *a, mp_t *b) +{ + return memcmp(a, b, len * MP_T_BYTES) == 0; +} + +static int +mpiszero(int len, mp_t *a) +{ + int i; + for (i = 0; i < len; i++) + if (a[i]) + return 0; + return 1; +} + #if 0 static void mpdump(int l, mp_t *a, char *s) { @@ -67,22 +95,11 @@ static void mpdump(int l, mp_t *a, char *s) } #endif -/* subtract mod if target >= mod */ +/* subtract mod from target. target >= mod */ static inline void mpsubmod(int len, mp_t *target, mp_t *mod) { int i; mp2_t n; - if (target[len - 1] < mod[len - 1]) - return; - if (target[len - 1] == mod[len - 1]) - { - for (i = len - 2; i >= 0; i--) - if (target[i] < mod[i]) - return; - else if (target[i] > mod[i]) - break; - } - /* target >= mod, subtract mod */ for (n = 0, i = 0; i < len; i++) { mp2_t n2 = (mp2_t)mod[i] + n; @@ -127,7 +144,7 @@ mpdomod(int len, mp_t *target, mp2_t x, mp_t *mod) x -= n; } target[i] = x; - if (x >= mod[i]) + if (x > mod[i] || (x == mod[i] && !mpisless(i, target, mod))) mpsubmod(i + 1, target, mod); } @@ -203,7 +220,7 @@ mppow_int(int len, mp_t *target, mp_t *t, mp_t *mod, int e) mpmul_inplace(len, target, t + len * e, t, t2, mod); } -/* target = b ^ e (b has to be < mod) */ +/* target = b ^ e (b < mod) */ static void mppow(int len, mp_t *target, mp_t *b, int elen, mp_t *e, mp_t *mod) { @@ -239,7 +256,7 @@ mppow(int len, mp_t *target, mp_t *b, int elen, mp_t *e, mp_t *mod) free(t); } -/* target = m1 * m2 (m1 has to be < mod) */ +/* target = m1 * m2 (m1 < mod) */ static void mpmul(int len, mp_t *target, mp_t *m1, int m2len, mp_t *m2, mp_t *mod) { @@ -249,34 +266,6 @@ mpmul(int len, mp_t *target, mp_t *m1, int m2len, mp_t *m2, mp_t *mod) free(tmp); } -static int -mpisless(int len, mp_t *a, mp_t *b) -{ - int i; - for (i = len - 1; i >= 0; i--) - if (a[i] < b[i]) - return 1; - else if (a[i] > b[i]) - return 0; - return 0; -} - -static int -mpisequal(int len, mp_t *a, mp_t *b) -{ - return memcmp(a, b, len * MP_T_BYTES) == 0; -} - -static int -mpiszero(int len, mp_t *a) -{ - int i; - for (i = 0; i < len; i++) - if (a[i]) - return 0; - return 1; -} - static void mpdec(int len, mp_t *a) { @@ -299,15 +288,9 @@ mpadd(int len, mp_t *target, mp_t *m1, mp_t *m2, mp_t *mod) target[i] = x; x >>= MP_T_BITS; } - if (x || !mpisless(len, target, mod)) - { - for (x = 0, i = 0; i < len; i++) - { - x = (mp2_t)target[i] - mod[i] - x; - target[i] = x; - x = x & ((mp2_t)1 << MP_T_BITS) ? 1 : 0; - } - } + if (x || target[len - 1] > mod[len - 1] || + (target[len -1 ] == mod[len - 1] && !mpisless(len - 1, target, mod))) + mpsubmod(len, target, mod); } /* target = m1 - m2 (m1, m2 < mod). target may be m1 or m2 */ @@ -342,6 +325,7 @@ mpdsa(int pl, mp_t *p, int ql, mp_t *q, mp_t *g, mp_t *y, mp_t *r, mp_t *s, int mp_t *tmp; mp_t *u1, *u2; mp_t *gu1, *yu2; + int res; #if 0 mpdump(pl, p, "p = "); mpdump(ql, q, "q = "); @@ -362,7 +346,7 @@ mpdsa(int pl, mp_t *p, int ql, mp_t *q, mp_t *g, mp_t *y, mp_t *r, mp_t *s, int mpdec(ql, tmp); /* tmp-- */ mpdec(ql, tmp); /* tmp-- */ w = mpnew(ql); - mppow(ql, w, s, ql, tmp, q); /* w = s ^ tmp (s ^ -1) */ + mppow(ql, w, s, ql, tmp, q); /* w = s ^ tmp = (s ^ -1) */ u1 = mpnew(pl); /* note pl */ /* order is important here: h can be >= q */ mpmul(ql, u1, w, hl, h, q); /* u1 = w * h */ @@ -384,19 +368,16 @@ mpdsa(int pl, mp_t *p, int ql, mp_t *q, mp_t *g, mp_t *y, mp_t *r, mp_t *s, int #if 0 mpdump(ql, tmp, "res = "); #endif - if (!mpisequal(ql, tmp, r)) - { - free(tmp); - return 0; - } + res = mpisequal(ql, tmp, r); free(tmp); - return 1; + return res; } static int mprsa(int nl, mp_t *n, int el, mp_t *e, mp_t *m, mp_t *c) { mp_t *tmp; + int res; #if 0 mpdump(nl, n, "n = "); mpdump(el, e, "e = "); @@ -412,13 +393,9 @@ mprsa(int nl, mp_t *n, int el, mp_t *e, mp_t *m, mp_t *c) #if 0 mpdump(nl, tmp, "res = "); #endif - if (!mpisequal(nl, tmp, c)) - { - free(tmp); - return 0; - } + res = mpisequal(nl, tmp, c); free(tmp); - return 1; + return res; } #if ENABLE_PGPVRFY_ED25519