/* See http://www.hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html#doubling-dbl-2008-hwcd */ static unsafe void dbl_p1p1(ge25519_p1p1 *r, ge25519_p2 *p) { fe25519 a, b, c, d; fe25519.fe25519_square(&a, &p->x); fe25519.fe25519_square(&b, &p->y); fe25519.fe25519_square(&c, &p->z); fe25519.fe25519_add(&c, &c, &c); fe25519.fe25519_neg(&d, &a); fe25519.fe25519_add(&r->x, &p->x, &p->y); fe25519.fe25519_square(&r->x, &r->x); fe25519.fe25519_sub(&r->x, &r->x, &a); fe25519.fe25519_sub(&r->x, &r->x, &b); fe25519.fe25519_add(&r->z, &d, &b); fe25519.fe25519_sub(&r->t, &r->z, &c); fe25519.fe25519_sub(&r->y, &d, &b); }
static unsafe void add_p1p1(ge25519_p1p1 *r, ge25519 *p, ge25519 *q) { fe25519 a, b, c, d, t, fd; fixed(Byte *ecdp = ecd) fe25519.fe25519_unpack(&fd, ecdp); fe25519.fe25519_sub(&a, &p->y, &p->x); // A = (Y1-X1)*(Y2-X2) fe25519.fe25519_sub(&t, &q->y, &q->x); fe25519.fe25519_mul(&a, &a, &t); fe25519.fe25519_add(&b, &p->x, &p->y); // B = (Y1+X1)*(Y2+X2) fe25519.fe25519_add(&t, &q->x, &q->y); fe25519.fe25519_mul(&b, &b, &t); fe25519.fe25519_mul(&c, &p->t, &q->t); //C = T1*k*T2 fe25519.fe25519_mul(&c, &c, &fd); fe25519.fe25519_add(&c, &c, &c); //XXX: Can save this addition by precomputing 2*ecd fe25519.fe25519_mul(&d, &p->z, &q->z); //D = Z1*2*Z2 fe25519.fe25519_add(&d, &d, &d); fe25519.fe25519_sub(&r->x, &b, &a); // E = B-A fe25519.fe25519_sub(&r->t, &d, &c); // F = D-C fe25519.fe25519_add(&r->z, &d, &c); // G = D+C fe25519.fe25519_add(&r->y, &b, &a); // H = B+A }
static unsafe void p1p1_to_p3(ge25519 *r, ge25519_p1p1 *p) { p1p1_to_p2((ge25519_p2 *)r, p); fe25519.fe25519_mul(&r->t, &p->x, &p->y); }
static Byte[] ge25519_neutral_t = new Byte[32]; // { 0 }; static unsafe void p1p1_to_p2(ge25519_p2 *r, ge25519_p1p1 *p) { fe25519.fe25519_mul(&r->x, &p->x, &p->t); fe25519.fe25519_mul(&r->y, &p->y, &p->z); fe25519.fe25519_mul(&r->z, &p->z, &p->t); }