progs/perftest.c: Use from Glibc syscall numbers.
[catacomb] / math / ec-test.c
index db59294..ff01a2e 100644 (file)
@@ -38,6 +38,8 @@
 #include <mLib/sub.h>
 
 #include "ec.h"
+#include "ectab.h"
+#include "ec-raw.h"
 #include "ec-test.h"
 
 /*----- Cardboard cut-out elliptic curve ----------------------------------*/
@@ -88,6 +90,12 @@ static ec *ecFIND(ec_curve *cc, ec *d, mp *x)
   return (EC_FIND(c->real, d, x));
 }
 
+static int ecCOMPR(ec_curve *cc, const ec *p)
+{
+  ecctx *c = (ecctx *)cc;
+  return (EC_COMPR(c->real, p));
+}
+
 static int ecCHECK(ec_curve *cc, const ec *p)
 {
   ecctx *c = (ecctx *)cc;
@@ -103,7 +111,7 @@ static int ecSAMEP(ec_curve *cc, ec_curve *dd)
 static const ec_ops ecops = {
   "cardboard",
   ecDESTROY, ecSAMEP, ecIN, ecOUT, ecFIX,
-  ecFIND, ecNEG, ecADD, ecSUB, ecDBL, ecCHECK
+  ecFIND, ecNEG, ecADD, ecSUB, ecDBL, ecCHECK, ecCOMPR
 };
 
 static ec_curve *ec_cutout(ec_curve *real, const char *name)
@@ -132,14 +140,26 @@ static void ecvcvt(const char *buf, dstr *d)
 {
   ec_curve *v;
   qd_parse qd;
+  const ecentry *ee;
+  ec_info ei;
 
   qd.p = buf;
   qd.e = 0;
+  for (ee = ectab; ee->name; ee++) {
+    if (qd_enum(&qd, ee->name) >= 0) {
+      ec_infofromdata(&ei, ee->data);
+      v = ei.c;
+      MP_DROP(ei.r); MP_DROP(ei.h);
+      EC_DESTROY(&ei.g);
+      goto found;
+    }
+  }
   if ((v = ec_curveparse(&qd)) == 0) {
     fprintf(stderr, "bad curve `%.*s|%s': %s\n",
-           qd.p - buf, buf, qd.p, qd.e);
+           (int)(qd.p - buf), buf, qd.p, qd.e);
     exit(1);
   }
+found:
   dstr_ensure(d, sizeof(v));
   *(ec_curve **)d->buf = ec_cutout(v, buf);
   d->len += sizeof(v);
@@ -165,7 +185,8 @@ static void eccvt(const char *p, dstr *d)
   d->len += sizeof(ec);
   ec_create(a);
   if (!ec_ptparse(&qd, a)) {
-    fprintf(stderr, "bad point `%.*s|%s': %s\n", qd.p - p, p, qd.p, qd.e);
+    fprintf(stderr, "bad point `%.*s|%s': %s\n",
+           (int)(qd.p - p), p, qd.p, qd.e);
     exit(1);
   }
 }
@@ -194,6 +215,8 @@ const test_type type_ec = { eccvt, ecdump };
 
 #ifdef TEST_RIG
 
+#include <mLib/macros.h>
+
 static void ecdestroy(ec_curve *c)
 {
   field *f = c->f;
@@ -211,7 +234,7 @@ static void ecdestroy(ec_curve *c)
     int ok = 1;                                                                \
     ec_##op(e, &c, a);                                                 \
     if (!EC_EQ(r, &c)) {                                               \
-      fprintf(stderr, #op "failed");                                   \
+      fprintf(stderr, #op " failed");                                  \
       fprintf(stderr, "\ncurve = "); type_ecurve.dump(v, stderr);      \
       fprintf(stderr, "\n    a = "); ecdodump(a, stderr);              \
       fprintf(stderr, "\n    r = "); ecdodump(r, stderr);              \
@@ -235,7 +258,7 @@ static void ecdestroy(ec_curve *c)
     int ok = 1;                                                                \
     ec_##op(e, &c, a, b);                                              \
     if (!EC_EQ(r, &c)) {                                               \
-      fprintf(stderr, #op "failed");                                   \
+      fprintf(stderr, #op " failed");                                  \
       fprintf(stderr, "\ncurve = "); type_ecurve.dump(v, stderr);      \
       fprintf(stderr, "\n    a = "); ecdodump(a, stderr);              \
       fprintf(stderr, "\n    b = "); ecdodump(b, stderr);              \
@@ -322,6 +345,82 @@ static int vfind(dstr v[])
   return (ok);
 }
 
+static int vec2osp(dstr v[])
+{
+  ec_curve *e = *(ec_curve **)v[0].buf;
+  unsigned f = *(int *)v[1].buf;
+  ec *p = (ec *)v[2].buf;
+  size_t n = 1 + 2*e->f->noctets;
+  dstr d = DSTR_INIT, dd = DSTR_INIT;
+  buf b;
+  int ok = 1;
+  int win, wantwin;
+
+  if (STRCMP(v[3].buf, ==, "FAIL")) wantwin = 0;
+  else { wantwin = 1; type_hex.cvt(v[3].buf, &d); }
+
+  dstr_ensure(&dd, n); buf_init(&b, dd.buf, n);
+
+  win = !ec_ec2osp(e, f, &b, p);
+  if (!win != !wantwin ||
+      (win && (BLEN(&b) != d.len ||
+              MEMCMP(BBASE(&b), !=, d.buf, BLEN(&b))))) {
+    ok = 0;
+    fprintf(stderr, "ec2osp failed");
+    fprintf(stderr, "\ncurve = "); type_ecurve.dump(v, stderr);
+    fprintf(stderr, "\n  fmt = 0x%02x", f);
+    fprintf(stderr, "\n    p = "); ecdodump(p, stderr);
+    fprintf(stderr, "\n want = ");
+    if (wantwin) type_hex.dump(&d, stderr);
+    else fprintf(stderr, "FAIL");
+    fprintf(stderr, "\nfound = ");
+    if (win) { dd.len = BLEN(&b); type_hex.dump(&dd, stderr); }
+    else fprintf(stderr, "FAIL");
+    fprintf(stderr, "\n");
+  }
+
+  dstr_destroy(&d); dstr_destroy(&dd);
+  EC_DESTROY(p); ecdestroy(e);
+  return (ok);
+}
+
+static int vos2ecp(dstr v[])
+{
+  ec_curve *e = *(ec_curve **)v[0].buf;
+  unsigned f = *(int *)v[1].buf;
+  int remain = *(int *)v[4].buf;
+  dstr d = DSTR_INIT;
+  ec *p, q = EC_INIT;
+  buf b;
+  int ok = 1;
+  int win;
+
+  if (STRCMP(v[3].buf, ==, "FAIL")) p = 0;
+  else { type_ec.cvt(v[3].buf, &d); p = (ec *)d.buf; }
+
+  buf_init(&b, v[2].buf, v[2].len);
+  win = !ec_os2ecp(e, f, &b, &q);
+
+  if (!win != !p || (win && (!EC_EQ(p, &q) || BLEFT(&b) != remain))) {
+    ok = 0;
+    fprintf(stderr, "os2ecp failed");
+    fprintf(stderr, "\ncurve = "); type_ecurve.dump(v, stderr);
+    fprintf(stderr, "\n  fmt = 0x%02x", f);
+    fprintf(stderr, "\ninput = "); type_hex.dump(&v[2], stderr);
+    fprintf(stderr, "\n want = ");
+    if (p) ecdodump(p, stderr); else fprintf(stderr, "FAIL");
+    fprintf(stderr, "\nfound = ");
+    if (win) ecdodump(&q, stderr); else fprintf(stderr, "FAIL");
+    fprintf(stderr, "\nremain= %d", remain);
+    fprintf(stderr, "\nleft  = %d", (int)BLEFT(&b));
+    fprintf(stderr, "\n");
+  }
+
+  if (p) EC_DESTROY(p); EC_DESTROY(&q); ecdestroy(e);
+  dstr_destroy(&d);
+  return (ok);
+}
+
 static test_chunk tests[] = {
   { "neg", vneg, { &type_ecurve, &type_ec, &type_ec } },
   { "dbl", vdbl, { &type_ecurve, &type_ec, &type_ec } },
@@ -330,6 +429,9 @@ static test_chunk tests[] = {
   { "mul", vmul, { &type_ecurve, &type_ec, &type_mp, &type_ec } },
   { "check", vcheck, { &type_ecurve, &type_ec, &type_int } },
   { "find", vfind, { &type_ecurve, &type_mp, &type_ec } },
+  { "ec2osp", vec2osp, { &type_ecurve, &type_int, &type_ec, &type_string } },
+  { "os2ecp", vos2ecp,
+    { &type_ecurve, &type_int, &type_hex, &type_string, &type_int } },
   { 0, 0, { 0 } }
 };