]> git.ipfire.org Git - thirdparty/libsolv.git/commitdiff
Improve ed25519 a bit
authorMichael Schroeder <mls@suse.de>
Tue, 19 May 2020 11:59:16 +0000 (13:59 +0200)
committerMichael Schroeder <mls@suse.de>
Tue, 19 May 2020 11:59:16 +0000 (13:59 +0200)
ext/solv_ed25519.h
ext/solv_pgpvrfy.c

index b48c3413b3b806309dca1834fd7af7421f0967c6..1ad43d926db7149751913f5eadb23620c7c625d4 100644 (file)
@@ -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);
index e4be692db460b10161a180cbc98ab70a4e1106f3..3e1a55923ea8edfe10a61e0667ccd7cb8ec7cc33 100644 (file)
@@ -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