#include <mLib/sub.h>
#include "ec.h"
+#include "ectab.h"
+#include "ec-raw.h"
#include "ec-test.h"
/*----- Cardboard cut-out elliptic curve ----------------------------------*/
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;
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)
{
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",
(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);
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); \
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); \
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") == 0) 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)) != 0))) {
+ 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") == 0) 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 } },
{ "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 } }
};