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);
}
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
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)
{
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))
#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;
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);
#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)
{
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)
{
}
#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;
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);
}
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)
{
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)
{
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)
{
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 */
mp_t *tmp;
mp_t *u1, *u2;
mp_t *gu1, *yu2;
+ int res;
#if 0
mpdump(pl, p, "p = ");
mpdump(ql, q, "q = ");
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 */
#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 = ");
#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