#include "mprand.h"
#include "fibrand.h"
#include "rsa.h"
+#include "mpint.h"
+#include "mptext.h"
#include "mpmont.h"
#include "mpbarrett.h"
#include "dh.h"
#include "pgen.h"
#include "ec.h"
#include "group.h"
+#include "x25519.h"
+#include "x448.h"
+#include "ed25519.h"
#include "cc.h"
#include "gcipher.h"
unsigned n; /* Number of factors */
unsigned i; /* Number of intervals (or zero) */
double t; /* Time for each interval (secs) */
+ mp *e; /* Public exponent */
unsigned f; /* Flags */
#define OF_NOCHECK 1u /* Don't do group checking */
} opts;
G_DESTROY(c->g, x);
}
+/* --- x25519 --- */
+
+typedef struct x25519_jobctx {
+ octet k[X25519_KEYSZ];
+ octet p[X25519_PUBSZ];
+} x25519_jobctx;
+
+static void *x25519_jobinit(opts *o)
+{
+ x25519_jobctx *c = CREATE(x25519_jobctx);
+ rand_get(RAND_GLOBAL, c->k, sizeof(c->k));
+ rand_get(RAND_GLOBAL, c->p, sizeof(c->p));
+ return (c);
+}
+
+static void x25519_jobrun(void *cc)
+ { x25519_jobctx *c = cc; octet z[X25519_OUTSZ]; x25519(z, c->k, c->p); }
+
+/* --- x448 --- */
+
+typedef struct x448_jobctx {
+ octet k[X448_KEYSZ];
+ octet p[X448_PUBSZ];
+} x448_jobctx;
+
+static void *x448_jobinit(opts *o)
+{
+ x448_jobctx *c = CREATE(x448_jobctx);
+ rand_get(RAND_GLOBAL, c->k, sizeof(c->k));
+ rand_get(RAND_GLOBAL, c->p, sizeof(c->p));
+ return (c);
+}
+
+static void x448_jobrun(void *cc)
+ { x448_jobctx *c = cc; octet z[X448_OUTSZ]; x448(z, c->k, c->p); }
+
+/* --- Ed25519 --- */
+
+typedef struct ed25519_signctx {
+ octet k[ED25519_KEYSZ];
+ octet K[ED25519_PUBSZ];
+ octet m[64];
+} ed25519_signctx;
+
+typedef struct ed25519_vrfctx {
+ octet K[ED25519_PUBSZ];
+ octet m[64];
+ octet sig[ED25519_SIGSZ];
+} ed25519_vrfctx;
+
+static void *ed25519_signinit(opts *o)
+{
+ ed25519_signctx *c = CREATE(ed25519_signctx);
+
+ rand_get(RAND_GLOBAL, c->k, sizeof(c->k));
+ rand_get(RAND_GLOBAL, c->m, sizeof(c->m));
+ ed25519_pubkey(c->K, c->k, sizeof(c->k));
+ return (c);
+}
+
+static void ed25519_signrun(void *cc)
+{
+ ed25519_signctx *c = cc;
+ octet sig[ED25519_SIGSZ];
+
+ ed25519_sign(sig, c->k, sizeof(c->k), c->K, c->m, sizeof(c->m));
+}
+
+static void *ed25519_vrfinit(opts *o)
+{
+ octet k[ED25519_KEYSZ];
+ ed25519_vrfctx *c = CREATE(ed25519_vrfctx);
+
+ rand_get(RAND_GLOBAL, k, sizeof(k));
+ rand_get(RAND_GLOBAL, c->m, sizeof(c->m));
+ ed25519_pubkey(c->K, k, sizeof(k));
+ ed25519_sign(c->sig, k, sizeof(k), c->K, c->m, sizeof(c->m));
+ return (c);
+}
+
+static void ed25519_vrfrun(void *cc)
+{
+ ed25519_vrfctx *c = cc;
+ ed25519_verify(c->K, c->m, sizeof(c->m), c->sig);
+}
+
/* --- RSA --- */
typedef struct rsapriv_ctx {
rsapriv_ctx *c = CREATE(rsapriv_ctx);
if (!o->fbits) o->fbits = 1024;
- rsa_gen(&c->rp, o->fbits, &rand_global, 0, pgen_evspin, 0);
+ if (!o->e) o->e = mp_fromulong(MP_NEW, 65537);
+ rsa_gen_e(&c->rp, o->fbits, o->e, &rand_global, 0, pgen_evspin, 0);
rsa_privcreate(&c->rpc, &c->rp, 0);
c->m = mprand_range(MP_NEW, c->rp.n, &rand_global, 0);
return (c);
rsapriv_ctx *c = CREATE(rsapriv_ctx);
if (!o->fbits) o->fbits = 1024;
- rsa_gen(&c->rp, o->fbits, &rand_global, 0, pgen_evspin, 0);
+ if (!o->e) o->e = mp_fromulong(MP_NEW, 65537);
+ rsa_gen_e(&c->rp, o->fbits, o->e, &rand_global, 0, pgen_evspin, 0);
rsa_privcreate(&c->rpc, &c->rp, fibrand_create(0));
c->m = mprand_range(MP_NEW, c->rp.n, &rand_global, 0);
return (c);
rsa_priv rp;
if (!o->fbits) o->fbits = 1024;
- rsa_gen(&rp, o->fbits, &rand_global, 0, pgen_evspin, 0);
+ if (!o->e) o->e = mp_fromulong(MP_NEW, 65537);
+ rsa_gen_e(&rp, o->fbits, o->e, &rand_global, 0, pgen_evspin, 0);
c->rp.n = MP_COPY(rp.n);
c->rp.e = MP_COPY(rp.e);
rsa_privfree(&rp);
{ "rsa-priv", rsapriv_init, rsapriv_run },
{ "rsa-priv-blind", rsaprivblind_init, rsapriv_run },
{ "rsa-pub", rsapub_init, rsapub_run },
+ { "x25519", x25519_jobinit, x25519_jobrun },
+ { "x448", x448_jobinit, x448_jobrun },
+ { "ed25519-sign", ed25519_signinit, ed25519_signrun },
+ { "ed25519-vrf", ed25519_vrfinit, ed25519_vrfrun },
{ "ksched", ksched_init, ksched_run },
{ "enc", enc_init, enc_run },
{ "hash", hash_init, hash_run },
return (u);
}
+static mp *mparg(const char *what, const char *p)
+{
+ char *q;
+ mp *x = mp_readstring(MP_NEW, p, &q, 0);
+ if (!x || *q) die(1, "bad %s `%s'", what, p);
+ return (x);
+}
+
static double farg(const char *what, const char *p)
{
char *q;
{ "group-bits", OPTF_ARGREQ, 0, 'B' },
{ "factors", OPTF_ARGREQ, 0, 'n' },
{ "intervals", OPTF_ARGREQ, 0, 'i' },
+ { "public-exponent", OPTF_ARGREQ, 0, 'e' },
{ "time", OPTF_ARGREQ, 0, 't' },
{ "no-check", 0, 0, 'q' },
{ 0, 0, 0, 0 }
};
- i = mdwopt(argc, argv, "hvulC:b:B:n:i:t:q", opts, 0, 0, 0);
+ i = mdwopt(argc, argv, "hvulC:b:B:n:i:e:t:q", opts, 0, 0, 0);
if (i < 0) break;
switch (i) {
case 'h': help(stdout); exit(0);
case 'b': o.fbits = uarg("field bits", optarg); break;
case 'B': o.gbits = uarg("subgroup bits", optarg); break;
case 'n': o.n = uarg("factor count", optarg); break;
+ case 'e':
+ mp_drop(o.e); o.e = mparg("public exponent", optarg);
+ if (MP_CMP(o.e, <, MP_THREE) || MP_EVENP(o.e))
+ die(1, "invalid public exponent");
+ break;
case 'i': o.i = uarg("interval count", optarg); break;
case 't': o.t = farg("interval length", optarg); break;
case 'q': o.f |= OF_NOCHECK; break;