Browse Source

Elligator now passes tests, but there are likely still missing preimages of rotations of the identity point. Also, projscaling elligator probably works, but it needs testing

master
Michael Hamburg 9 years ago
parent
commit
629a782fff
3 changed files with 28 additions and 14 deletions
  1. +17
    -11
      aux/decaffeinate_curve25519.sage
  2. +3
    -1
      src/decaf_fast.c
  3. +8
    -2
      test/test_decaf.cxx

+ 17
- 11
aux/decaffeinate_curve25519.sage View File

@@ -67,24 +67,30 @@ def decaf_encode_from_E_c(X,Y):
# Precompute
sd = sqrt(F(1-d))
zx = Z^2-X^2
TZ = T*Z
# comments in case of identity point
# (1,0) or (0,1)
zx = Z^2-X^2 # 0^2 or 1 * Z^2
TZ = T*Z # 0 * Z^2
assert zx.is_square
ooAll = isqrt(zx*TZ^2)
osx = ooAll * TZ
ooTZ = ooAll * zx * osx
ooAll = isqrt(zx*TZ^2) # inf^2 or inf * 1/Z^3
osx = ooAll * TZ # inf or 1 * 1/Z
ooTZ = ooAll * zx * osx # inf * 1/Z^2
floop = qpositive(T^2 * ooTZ) or doPinkBikeShed
floop = qpositive(T^2 * ooTZ) or doPinkBikeShed # 0
if floop:
frob = zx * ooTZ
frob = zx * ooTZ # 0 or inf
# Y = 0 or 1
else:
frob = sd
Y = -X
frob = sd # sd
Y = -X # -1 or 0 * Z
osx *= frob
osx *= frob # 1 or inf * 1/Z || inf sd or sd * 1/Z
# y * osx = 0 or inf or -inf sd or 0 sd
# y * ootz * z = 1 or inf or inf sd or 0^2 sd
# s = 0 or 1 or inf sd or
if qpositive(-2*osx*Z) != floop: osx = -osx
s = Y*(ooTZ*Z + osx)
s = Y*(ooTZ*Z + osx) #
if not qpositive(s): s = -s
return s


+ 3
- 1
src/decaf_fast.c View File

@@ -1183,13 +1183,14 @@ API_NS(invert_elligator_nonuniform) (
gf_mul(b,c,a);
gf_sub(b,ONE,b); /* t+1 */
gf_sqr(c,a); /* s^2 */
decaf_bool_t is_identity = gf_eq(p->t,ZERO);
{ /* identity adjustments */
/* in case of identity, currently c=0, t=0, b=1, will encode to 1 */
/* if hint is 0, -> 0 */
/* if hint is to neg t/s, then go to infinity, effectively set s to 1 */
decaf_bool_t is_identity = gf_eq(p->x,ZERO);
cond_sel(c,c,ONE,is_identity & sgn_t_over_s);
cond_sel(b,b,ZERO,is_identity & ~sgn_t_over_s & ~sgn_s); /* identity adjust */
//cond_neg(b,is_identity & sgn_ed_T);
}
gf_mlw(d,c,2*EDWARDS_D-1); /* $d = (2d-a)s^2 */
@@ -1203,6 +1204,7 @@ API_NS(invert_elligator_nonuniform) (
cond_neg(b, sgn_r0^hibit(b));
succ &= ~(gf_eq(b,ZERO) & sgn_r0);
succ &= ~(is_identity & sgn_ed_T); /* FIXME: preimages of rotation */
gf_encode(recovered_hash, b);
/* TODO: deal with overflow flag */


+ 8
- 2
test/test_decaf.cxx View File

@@ -168,10 +168,10 @@ static void test_elligator() {
decaf::SecureBuffer *alts[NHINTS];
bool successes[NHINTS];

for (int i=0; i<NTESTS && (test.passing_now || i < 100); i++) {
for (int i=0; i<NTESTS/10 && (test.passing_now || i < 100); i++) {
size_t len = (i % (2*Point::HASH_BYTES + 3)); // FIXME: 0
decaf::SecureBuffer b1(len);
rng.read(b1);
if (i!=Point::HASH_BYTES) rng.read(b1); /* special test case */
if (i==1) b1[0] = 1; /* special case test */
if (len >= Point::HASH_BYTES) b1[Point::HASH_BYTES-1] &= 0x7F; // FIXME MAGIC
Point s = Point::from_hash(b1);
@@ -203,6 +203,12 @@ static void test_elligator() {
hexprint("x",b1);
hexprint("X",*alts[j]);
}
/*
if (i == Point::HASH_BYTES) {
printf("Identity, hint = %d\n", j);
hexprint("einv(0)",*alts[j]);
}
*/
}
}


Loading…
Cancel
Save