5 #include <mLib/alloc.h>
12 #include "field-guts.h"
14 static void puthex(const char *name
, mp
*x
, size_t n
)
20 if (!n
) n
= mp_octets(x
);
26 hex_encode(&hc
, p
, n
, &d
);
27 hex_encode(&hc
, 0, 0, &d
);
28 printf(" %s 0x", name
);
29 dstr_write(&d
, stdout
);
35 int main(int argc
, char *argv
[])
45 mp
*x
, *y
= 0, *yy
= 0;
51 if ((c
= ec_curveparse(&qd
)) == 0 || !qd_eofp(&qd
)) {
52 fprintf(stderr
, "bad curve: %s\n", qd
.e
);
58 ei
.r
= mp_readstring(MP_NEW
, argv
[2], 0, 0);
59 ei
.h
= mp_readstring(MP_NEW
, argv
[3], 0, 0);
63 hex_decode(&hc
, argv
[4], strlen(argv
[4]), &d
);
64 hex_decode(&hc
, 0, 0, &d
);
70 fprintf(stderr
, "missing x\n");
73 x
= mp_loadb(MP_NEW
, p
+ 1, n
);
75 if (d
.len
< 2 * n
+ 1) {
76 fprintf(stderr
, "missing y\n");
79 y
= mp_loadb(MP_NEW
, p
+ n
+ 1, n
);
82 if (!ec_find(c
, &pt
, x
)) {
83 fprintf(stderr
, "no matching y\n");
88 switch (F_TYPE(c
->f
)) {
90 if (!MP_ODDP(yy
) != !(p
[0] & 1))
91 yy
= mp_sub(yy
, c
->f
->m
, yy
);
95 yy
= F_SQRT(c
->f
, MP_NEW
, c
->b
);
97 mp
*xin
= F_IN(c
->f
, MP_NEW
, x
);
98 mp
*xx
= F_SQR(c
->f
, MP_NEW
, xin
);
99 mp
*b
= F_MUL(c
->f
, MP_NEW
, xx
, c
->a
);
100 mp
*xxx
= F_MUL(c
->f
, MP_NEW
, xx
, xin
);
101 b
= F_ADD(c
->f
, b
, b
, xxx
);
102 b
= F_ADD(c
->f
, b
, b
, c
->b
);
103 xx
= F_INV(c
->f
, xx
, xx
);
104 b
= F_MUL(c
->f
, b
, b
, xx
);
106 yy
= F_QUADSOLVE(c
->f
, MP_NEW
, b
);
107 xx
= F_OUT(c
->f
, xx
, yy
);
108 if (!MP_ODDP(xx
) != !(p
[0] & 1))
109 yy
= gf_add(yy
, yy
, MP_ONE
);
110 yy
= F_MUL(c
->f
, yy
, yy
, xin
);
111 yy
= F_OUT(c
->f
, yy
, yy
);
120 if (y
&& yy
&& !MP_EQ(y
, yy
)) {
121 fprintf(stderr
, "inconsistent answers\n");
125 ei
.g
.y
= mp_copy(y ? y
: yy
);
126 mp_drop(y
); mp_drop(yy
);
129 if ((err
= ec_checkinfo(&ei
, &rand_global
)) != 0)
130 fprintf(stderr
, "bad curve: %s\n", err
);
131 puthex("p", ei
.c
->f
->m
, 0);
132 if (strcmp(F_NAME(ei
.c
->f
), "binnorm") == 0) {
133 fctx_binnorm
*fc
= (fctx_binnorm
*)ei
.c
->f
;
134 puthex("beta", fc
->ntop
.r
[fc
->ntop
.n
- 1], c
->f
->noctets
);
136 t
= F_OUT(ei
.c
->f
, t
, ei
.c
->a
); puthex("a", t
, c
->f
->noctets
);
137 t
= F_OUT(ei
.c
->f
, t
, ei
.c
->b
); puthex("b", t
, c
->f
->noctets
);
138 puthex("r", ei
.r
, c
->f
->noctets
);
139 printf(" h "); mp_writefile(ei
.h
, stdout
, 10); putchar('\n');
140 puthex("gx", ei
.g
.x
, c
->f
->noctets
);
141 puthex("gy", ei
.g
.y
, c
->f
->noctets
);