From eab2a41d1351c20c16b4b79cd7f4e0b18f24b5d0 Mon Sep 17 00:00:00 2001 From: Mike Hamburg Date: Thu, 9 Jul 2015 18:45:45 -0700 Subject: [PATCH] switch from xy positive to 1/xy positive; this is because it can make laddered direct_scalarmul almost sane. almost. --- aux/decaffeinate_curve25519.sage | 8 +++--- src/decaf_fast.c | 49 +++++++++++++++++++++----------- test/bench_decaf.cxx | 1 - test/test_decaf.cxx | 1 - 4 files changed, 37 insertions(+), 22 deletions(-) diff --git a/aux/decaffeinate_curve25519.sage b/aux/decaffeinate_curve25519.sage index ef07e84..af89366 100644 --- a/aux/decaffeinate_curve25519.sage +++ b/aux/decaffeinate_curve25519.sage @@ -33,8 +33,8 @@ def M_to_E(P): def decaf_encode_from_E(X,Y): assert X^2 + Y^2 == 1 + d*X^2*Y^2 - if not (qpositive(X*Y) or doPinkBikeShed): X,Y = Y,-X - assert qpositive(X*Y) + if not (X==0 or Y==0 or qpositive(1/(X*Y)) or doPinkBikeShed): X,Y = Y,-X + assert X==0 or Y==0 or qpositive(1/(X*Y)) assert (1-X^2).is_square() sx = sqrt(1-X^2) @@ -76,7 +76,7 @@ def decaf_encode_from_E_c(X,Y): osx = ooAll * TZ # inf or 1 * 1/Z ooTZ = ooAll * zx * osx # inf * 1/Z^2 - floop = qpositive(T^2 * ooTZ) or doPinkBikeShed # 0 + floop = qpositive(Z^2 * ooTZ) or doPinkBikeShed # 0 if floop: frob = zx * ooTZ # 0 or inf # Y = 0 or 1 @@ -103,7 +103,7 @@ def decaf_decode_to_E(s): t = sqrt(s^4 + (2-4*d)*s^2 + 1) if not qpositive(t/s): t = -t X,Y = 2*s / (1+s^2), (1-s^2) / t - assert qpositive(X*Y) or doPinkBikeShed + assert X==0 or Y==0 or qpositive(1/(X*Y)) or doPinkBikeShed return X,Y def decaf_decode_to_E_c(s): diff --git a/src/decaf_fast.c b/src/decaf_fast.c index d81c1bd..5409c65 100644 --- a/src/decaf_fast.c +++ b/src/decaf_fast.c @@ -226,6 +226,14 @@ static decaf_word_t hibit(const gf x) { return -(y->limb[0]&1); } +/** Return high bit of x = low bit of 2x mod p */ +static decaf_word_t lobit(const gf x) { + gf y; + gf_cpy(y,x); + gf_canon(y); + return -(y->limb[0]&1); +} + /** {extra,accum} - sub +? p * Must have extra <= 1 */ @@ -492,8 +500,8 @@ static void deisogenize ( decaf_bool_t rotate; { gf e; - gf_sqr(e, t); - gf_mul(a, e, b); + gf_sqr(e, p->z); + gf_mul(a, e, b); /* z^2 / tz = z/t = 1/xy */ rotate = hibit(a) ^ toggle_rotation; /* * Curve25519: cond select between zx * 1/tz or sqrt(1-d); y=-x @@ -540,30 +548,39 @@ decaf_bool_t API_NS(point_decode) ( succ &= allow_identity | ~zero; succ &= ~hibit(s); gf_sqr ( a, s ); - gf_add ( f, ONE, a ); /* 1+s^2 = 1+as^2 since a=1 */ + gf_sub ( f, ONE, a ); /* f = 1-s^2 = 1-as^2 since a=1 */ succ &= ~ gf_eq( f, ZERO ); gf_sqr ( b, f ); - gf_mlw ( c, a, -4*EDWARDS_D ); + gf_mlw ( c, a, 4-4*EDWARDS_D ); gf_add ( c, c, b ); /* t^2 */ - gf_mul ( d, f, s ); /* s(1+s^2) for denoms */ + gf_mul ( d, f, s ); /* s(1-s^2) for denoms */ gf_sqr ( e, d ); gf_mul ( b, c, e ); - succ &= gf_isqrt_chk ( e, b, DECAF_TRUE ); /* e = "the" */ + succ &= gf_isqrt_chk ( e, b, DECAF_TRUE ); /* e = 1/(t s (1-s^2)) */ gf_mul ( b, e, d ); /* 1/t */ - gf_mul ( d, e, c ); /* d = later "the" = t / (s(1+s^2)) */ + gf_mul ( d, e, c ); /* d = t / (s(1-s^2)) */ gf_mul ( e, d, f ); /* t/s */ - gf_sub ( a, ONE, a); /* 1-s^2 */ + decaf_bool_t negtos = hibit(e); + cond_neg(b, negtos); + cond_neg(d, negtos); + + gf_add ( p->z, ONE, a); /* Z = 1+s^2 */ + succ &= ~gf_eq( p->z, ZERO ); /* FUTURE: unnecessary? */ + + gf_mul ( a, p->z, d); /* t(1+s^2) / s(1-s^2) = 2/xy */ + succ &= ~lobit(a); /* = ~hibit(a/2), since hibit(x) = lobit(2x) */ - gf_mul ( p->y, a, b ); /* y = (1-s^2) / t */ - gf_sub ( d, e, d ); /* t/s - t/ s(1+s^2) = st / (1+s^2) */ - gf_mul ( c, d, b ); /* s/(1+s^2) */ - gf_mul ( b, c, SQRT_MINUS_ONE ); /* is/(1+s^2) */ - gf_add ( p->x, b, b ); /* 2is */ - cond_neg ( p->x, hibit(e) ); - gf_mul ( p->t, p->x, p->y ); + gf_mul ( a, f, b ); /* y = (1-s^2) / t */ + gf_mul ( p->y, p->z, a ); /* Y = yZ */ + gf_add ( p->x, s, s ); + gf_mul ( p->t, p->x, a ); /* T = 2s (1-as^2)/t */ - gf_cpy ( p->z, ONE ); + /* TODO: integrate */ + gf_cpy(a, p->x); + gf_mul(p->x, a, SQRT_MINUS_ONE); + gf_cpy(a, p->t); + gf_mul(p->t, a, SQRT_MINUS_ONE); p->y->limb[0] -= zero; diff --git a/test/bench_decaf.cxx b/test/bench_decaf.cxx index 9416741..b28e1ac 100644 --- a/test/bench_decaf.cxx +++ b/test/bench_decaf.cxx @@ -69,7 +69,6 @@ static void printSI(double x, const char *unit, const char *spacer = " ") { class Benchmark { static const int NTESTS = 20, NSAMPLES=50, DISCARD=2; static double totalCy, totalS; - /* FIXME Tcy if get descheduled */ public: int i, j, ntests, nsamples; double begin; diff --git a/test/test_decaf.cxx b/test/test_decaf.cxx index a659856..46a7be7 100644 --- a/test/test_decaf.cxx +++ b/test/test_decaf.cxx @@ -306,7 +306,6 @@ static void test_ec() { "unih = hash+add" ); - point_check(test,p,q,r,x,0,Point(x.direct_scalarmul(decaf::SecureBuffer(p))),x*p,"direct mul"); } }