5 #include <mLib/alloc.h>
8 #include <mLib/macros.h>
13 #include "field-guts.h"
15 static void puthex(const char *name
, mp
*x
, size_t n
)
21 if (!n
) n
= mp_octets(x
);
27 hex_encode(&hc
, p
, n
, &d
);
28 hex_encode(&hc
, 0, 0, &d
);
29 printf(" %s 0x", name
);
30 dstr_write(&d
, stdout
);
36 int main(int argc
, char *argv
[])
46 mp
*x
, *y
= 0, *yy
= 0;
52 if ((c
= ec_curveparse(&qd
)) == 0 || !qd_eofp(&qd
)) {
53 fprintf(stderr
, "bad curve: %s\n", qd
.e
);
59 ei
.r
= mp_readstring(MP_NEW
, argv
[2], 0, 0);
60 ei
.h
= mp_readstring(MP_NEW
, argv
[3], 0, 0);
64 hex_decode(&hc
, argv
[4], strlen(argv
[4]), &d
);
65 hex_decode(&hc
, 0, 0, &d
);
71 fprintf(stderr
, "missing x\n");
74 x
= mp_loadb(MP_NEW
, p
+ 1, n
);
76 if (d
.len
< 2 * n
+ 1) {
77 fprintf(stderr
, "missing y\n");
80 y
= mp_loadb(MP_NEW
, p
+ n
+ 1, n
);
83 if (!ec_find(c
, &pt
, x
)) {
84 fprintf(stderr
, "no matching y\n");
89 switch (F_TYPE(c
->f
)) {
91 if (!MP_ODDP(yy
) != !(p
[0] & 1))
92 yy
= mp_sub(yy
, c
->f
->m
, yy
);
96 yy
= F_SQRT(c
->f
, MP_NEW
, c
->b
);
98 mp
*xin
= F_IN(c
->f
, MP_NEW
, x
);
99 mp
*xx
= F_SQR(c
->f
, MP_NEW
, xin
);
100 mp
*b
= F_MUL(c
->f
, MP_NEW
, xx
, c
->a
);
101 mp
*xxx
= F_MUL(c
->f
, MP_NEW
, xx
, xin
);
102 b
= F_ADD(c
->f
, b
, b
, xxx
);
103 b
= F_ADD(c
->f
, b
, b
, c
->b
);
104 xx
= F_INV(c
->f
, xx
, xx
);
105 b
= F_MUL(c
->f
, b
, b
, xx
);
107 yy
= F_QUADSOLVE(c
->f
, MP_NEW
, b
);
108 xx
= F_OUT(c
->f
, xx
, yy
);
109 if (!MP_ODDP(xx
) != !(p
[0] & 1))
110 yy
= gf_add(yy
, yy
, MP_ONE
);
111 yy
= F_MUL(c
->f
, yy
, yy
, xin
);
112 yy
= F_OUT(c
->f
, yy
, yy
);
121 if (y
&& yy
&& !MP_EQ(y
, yy
)) {
122 fprintf(stderr
, "inconsistent answers\n");
126 ei
.g
.y
= mp_copy(y ? y
: yy
);
127 mp_drop(y
); mp_drop(yy
);
130 if ((err
= ec_checkinfo(&ei
, &rand_global
)) != 0)
131 fprintf(stderr
, "bad curve: %s\n", err
);
132 puthex("p", ei
.c
->f
->m
, 0);
133 if (STRCMP(F_NAME(ei
.c
->f
), ==, "binnorm")) {
134 fctx_binnorm
*fc
= (fctx_binnorm
*)ei
.c
->f
;
135 puthex("beta", fc
->ntop
.r
[fc
->ntop
.n
- 1], c
->f
->noctets
);
137 t
= F_OUT(ei
.c
->f
, t
, ei
.c
->a
); puthex("a", t
, c
->f
->noctets
);
138 t
= F_OUT(ei
.c
->f
, t
, ei
.c
->b
); puthex("b", t
, c
->f
->noctets
);
139 puthex("r", ei
.r
, c
->f
->noctets
);
140 printf(" h "); mp_writefile(ei
.h
, stdout
, 10); putchar('\n');
141 puthex("gx", ei
.g
.x
, c
->f
->noctets
);
142 puthex("gy", ei
.g
.y
, c
->f
->noctets
);