Browse Source

switch from xy positive to 1/xy positive; this is because it can make laddered direct_scalarmul almost sane. almost.

master
Mike Hamburg 9 years ago
parent
commit
eab2a41d13
4 changed files with 37 additions and 22 deletions
  1. +4
    -4
      aux/decaffeinate_curve25519.sage
  2. +33
    -16
      src/decaf_fast.c
  3. +0
    -1
      test/bench_decaf.cxx
  4. +0
    -1
      test/test_decaf.cxx

+ 4
- 4
aux/decaffeinate_curve25519.sage View File

@@ -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):


+ 33
- 16
src/decaf_fast.c View File

@@ -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;


+ 0
- 1
test/bench_decaf.cxx View File

@@ -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;


+ 0
- 1
test/test_decaf.cxx View File

@@ -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");
}
}


Loading…
Cancel
Save