5 #include <mLib/alloc.h>
13 static void puthex(const char *name
, mp
*x
, size_t n
)
19 if (!n
) n
= mp_octets(x
);
25 hex_encode(&hc
, p
, n
, &d
);
26 hex_encode(&hc
, 0, 0, &d
);
27 printf(" %s 0x", name
);
28 dstr_write(&d
, stdout
);
34 int main(int argc
, char *argv
[])
44 mp
*x
, *y
= 0, *yy
= 0;
49 if ((c
= ec_curveparse(&qd
)) == 0 || !qd_eofp(&qd
)) {
50 fprintf(stderr
, "bad curve: %s\n", qd
.e
);
56 ei
.r
= mp_readstring(MP_NEW
, argv
[2], 0, 0);
57 ei
.h
= mp_readstring(MP_NEW
, argv
[3], 0, 0);
61 hex_decode(&hc
, argv
[4], strlen(argv
[4]), &d
);
62 hex_decode(&hc
, 0, 0, &d
);
68 fprintf(stderr
, "missing x\n");
71 x
= mp_loadb(MP_NEW
, p
+ 1, n
);
73 if (d
.len
< 2 * n
+ 1) {
74 fprintf(stderr
, "missing y\n");
77 y
= mp_loadb(MP_NEW
, p
+ n
+ 1, n
);
80 if (!EC_FIND(c
, &pt
, x
)) {
81 fprintf(stderr
, "no matching y\n");
86 switch (F_TYPE(c
->f
)) {
88 if (!MP_ISODD(yy
) != !(p
[0] & 1))
89 yy
= mp_sub(yy
, c
->f
->m
, yy
);
93 yy
= F_SQRT(c
->f
, MP_NEW
, c
->b
);
95 mp
*xx
= F_SQR(c
->f
, MP_NEW
, x
);
96 mp
*b
= F_MUL(c
->f
, MP_NEW
, xx
, c
->a
);
97 mp
*xxx
= F_MUL(c
->f
, MP_NEW
, xx
, x
);
98 b
= F_ADD(c
->f
, b
, b
, xxx
);
99 b
= F_ADD(c
->f
, b
, b
, c
->b
);
100 xx
= F_INV(c
->f
, xx
, xx
);
101 b
= F_MUL(c
->f
, b
, b
, xx
);
104 yy
= F_QUADSOLVE(c
->f
, MP_NEW
, b
);
105 if (!MP_ISODD(yy
) != !(p
[0] & 1))
106 yy
= mp_add(yy
, yy
, MP_ONE
);
107 yy
= F_MUL(c
->f
, yy
, yy
, x
);
114 if (y
&& yy
&& !MP_EQ(y
, yy
)) {
115 fprintf(stderr
, "inconsistent answers\n");
119 ei
.g
.y
= mp_copy(y ? y
: yy
);
120 mp_drop(y
); mp_drop(yy
);
123 if ((err
= ec_checkinfo(&ei
, &rand_global
)) != 0) {
124 fprintf(stderr
, "bad curve: %s\n", err
);
127 puthex("p", ei
.c
->f
->m
, 0);
128 puthex("a", ei
.c
->a
, c
->f
->noctets
);
129 puthex("b", ei
.c
->b
, c
->f
->noctets
);
130 puthex("r", ei
.r
, c
->f
->noctets
);
131 printf(" h "); mp_writefile(ei
.h
, stdout
, 10); putchar('\n');
132 puthex("gx", ei
.g
.x
, c
->f
->noctets
);
133 puthex("gy", ei
.g
.y
, c
->f
->noctets
);