Commit 9de0d1a3 authored by Johan Pascal's avatar Johan Pascal

Merge with master from the original depot

git://git.code.sf.net/p/ed448goldilocks/code
parents 69308cbf 15c3f7b7
......@@ -20,11 +20,11 @@ BUILD_IBIN = build/obj/bin
DOXYGEN ?= doxygen
ifeq ($(UNAME),Darwin)
CC = clang
CXX = clang++
CC ?= clang
CXX ?= clang++
else
CC = gcc
CXX = g++
CC ?= gcc
CXX ?= g++
endif
LD = $(CC)
LDXX = $(CXX)
......
......@@ -121,6 +121,8 @@ class QuotientEdwardsPoint(object):
else:
return self.__class__(-self.x, -self.y)
def doubleAndEncodeSpec(self):
return (self+self).encode()
# Utility functions
@classmethod
......@@ -203,7 +205,42 @@ class RistrettoPoint(QuotientEdwardsPoint):
if negative(isr^2*num*y*t): y = -y
s = isr*y*(z-y)
return self.gfToBytes(s,mustBePositive=True)
@optimized_version_of("doubleAndEncodeSpec")
def doubleAndEncode(self):
X,Y,Z,T = self.xyzt()
a,d,mneg = self.a,self.d,self.mneg
if self.cofactor==8:
e = 2*X*Y
f = Z^2+d*T^2
g = Y^2-a*X^2
h = Z^2-d*T^2
inv1 = inv0(e*f*g*h)
z_inv = inv1*e*g # 1 / (f*h)
t_inv = inv1*f*h
if negative(e*g*z_inv):
if a==-1: sqrta = self.i
else: sqrta = -1
e,f,g,h = g,h,-e,f*sqrta
factor = self.i
else:
factor = self.magic
if negative(h*e*z_inv): g=-g
s = (h-g)*factor*g*t_inv
else:
foo = Y^2+a*X^2
bar = X*Y
den = inv0(foo*bar)
if negative(2*bar^2*den): tmp = a*X^2
else: tmp = Y^2
s = self.magic*(Z^2-tmp)*foo*den
return self.gfToBytes(s,mustBePositive=True)
@classmethod
......@@ -466,6 +503,54 @@ class Decaf_1_1_Point(QuotientEdwardsPoint):
x = 2*s / (1+a*s^2)
y = (1-a*s^2) / t
return cls(x,sgn*y)
@optimized_version_of("doubleAndEncodeSpec")
def doubleAndEncode(self):
X,Y,Z,T = self.xyzt()
a,d = self.a,self.d
if self.cofactor == 8:
# Cofactor 8 version
# Simulate IMAGINE_TWIST because that's how libdecaf does it
X = self.i*X
T = self.i*T
a = -a
d = -d
# TODO: This is only being called for a=-1, so could
# be wrong for a=1
e = 2*X*Y
f = Y^2+a*X^2
g = Y^2-a*X^2
h = Z^2-d*T^2
eim = e*self.isoMagic
inv = inv0(eim*g*f*h)
fh_inv = eim*g*inv*self.i
if negative(eim*g*fh_inv):
idf = g*self.isoMagic*self.i
bar = f
foo = g
test = eim*f
else:
idf = eim
bar = h
foo = -eim
test = g*h
if negative(test*fh_inv): bar =- bar
s = idf*(foo+bar)*inv*f*h
else:
xy = X*Y
h = Z^2-d*T^2
inv = inv0(xy*h)
if negative(inv*2*xy^2*self.isoMagic): tmp = Y
else: tmp = X
s = tmp^2*h*inv # = X/Y or Y/X, interestingly
return self.gfToBytes(s,mustBePositive=True)
@classmethod
def elligatorSpec(cls,r0,fromR=False):
......@@ -696,7 +781,6 @@ def test(cls,n):
if Q1 + Q0 != Q2: raise TestFailedException("Scalarmul doesn't work")
Q = Q1
def testElligator(cls,n):
print "Testing elligator on %s" % cls.__name__
for i in xrange(n):
......@@ -716,9 +800,6 @@ def testElligator(cls,n):
#break
else:
pass # TODO
def gangtest(classes,n):
print "Gang test",[cls.__name__ for cls in classes]
......@@ -747,18 +828,37 @@ def gangtest(classes,n):
print c,binascii.hexlify(ret)
print
test(Ed25519Point,100)
test(NegEd25519Point,100)
test(IsoEd25519Point,100)
test(IsoEd448Point,100)
test(TwistedEd448GoldilocksPoint,100)
test(Ed448GoldilocksPoint,100)
testElligator(Ed25519Point,100)
testElligator(NegEd25519Point,100)
testElligator(IsoEd25519Point,100)
testElligator(IsoEd448Point,100)
testElligator(Ed448GoldilocksPoint,100)
testElligator(TwistedEd448GoldilocksPoint,100)
gangtest([IsoEd448Point,TwistedEd448GoldilocksPoint,Ed448GoldilocksPoint],100)
gangtest([Ed25519Point,IsoEd25519Point],100)
def testDoubleAndEncode(cls,n):
print "Testing doubleAndEncode on %s" % cls.__name__
P = cls()
for i in xrange(cls.cofactor):
Q = P.torque()
assert P.doubleAndEncode() == Q.doubleAndEncode()
P = Q
for i in xrange(n):
r1 = randombytes(cls.encLen)
r2 = randombytes(cls.encLen)
u = cls.elligator(r1) + cls.elligator(r2)
assert u.doubleAndEncode() == u.torque().doubleAndEncode()
testDoubleAndEncode(Ed25519Point,100)
testDoubleAndEncode(NegEd25519Point,100)
testDoubleAndEncode(IsoEd25519Point,100)
testDoubleAndEncode(IsoEd448Point,100)
testDoubleAndEncode(TwistedEd448GoldilocksPoint,100)
#test(Ed25519Point,100)
#test(NegEd25519Point,100)
#test(IsoEd25519Point,100)
#test(IsoEd448Point,100)
#test(TwistedEd448GoldilocksPoint,100)
#test(Ed448GoldilocksPoint,100)
#testElligator(Ed25519Point,100)
#testElligator(NegEd25519Point,100)
#testElligator(IsoEd25519Point,100)
#testElligator(IsoEd448Point,100)
#testElligator(Ed448GoldilocksPoint,100)
#testElligator(TwistedEd448GoldilocksPoint,100)
#gangtest([IsoEd448Point,TwistedEd448GoldilocksPoint,Ed448GoldilocksPoint],100)
#gangtest([Ed25519Point,IsoEd25519Point],100)
......@@ -133,8 +133,11 @@ for curve,data in curve_data.items():
data["eddsa_sigma_iso"] = 0
if "rist_base_decoded" not in data:
def xord(x):
if isinstance(x,str): return ord(x)
else: return x
data["rist_base_decoded"] = sum(
ord(b)<<(8*i) for i,b in enumerate(unhexlify(data["rist_base"]))
xord(b)<<(8*i) for i,b in enumerate(unhexlify(data["rist_base"]))
)
if "imagine_twist" not in data:
......
......@@ -776,7 +776,7 @@ decaf_bool_t API_NS(point_eq) ( const point_t p, const point_t q ) {
gf_mul ( b, q->y, p->x );
mask_t succ = gf_eq(a,b);
#if (COFACTOR == 8) && IMAGINE_TWIST
#if (COFACTOR == 8)
gf_mul ( a, p->y, q->y );
gf_mul ( b, q->x, p->x );
#if !(IMAGINE_TWIST)
......
......@@ -305,7 +305,7 @@ public:
*/
inline explicit Point(const FixedBlock<SER_BYTES> &buffer, bool allow_identity=true)
/*throw(CryptoException)*/ {
if (DECAF_SUCCESS != decode(buffer,allow_identity ? DECAF_TRUE : DECAF_FALSE)) {
if (DECAF_SUCCESS != decode(buffer,allow_identity)) {
throw CryptoException();
}
}
......
......@@ -10,6 +10,7 @@ p_tor4 = E.lift_x(-1)
Tor = [p_tor4 * i for i in xrange(4)]
q = 2^446-0x8335dc163bb124b65129c96fde933d8d723a70aadc873d6d54a7bb0d
FQ = GF(q)
isoMagic = 1/sqrt(F(39082/39081)-1)
passing = True
......@@ -195,7 +196,16 @@ class DecafScalar():
return True
class DecafPoint():
_UNDER = c_uint64 * int(8*4)
@staticmethod
def _UNDER():
size = int(8*8*4)
alignment = 32
buf1 = bytearray(size+alignment-1)
buf2 = (c_char * int(size+alignment-1)).from_buffer(buf1)
raw_addr = addressof(buf2)
offset = (-raw_addr) % alignment
return (c_char*size).from_buffer(buf2,int(offset))
def __init__(self,cstruct=None,point=None):
if cstruct is None:
cstruct = DecafPoint._UNDER()
......@@ -222,12 +232,11 @@ class DecafPoint():
@staticmethod
def _sage_deser(str):
s = from_le(str)
if s > (F.cardinality()-1)/2: raise Exception("Point didn't decode")
if is_odd(s): raise Exception("Point didn't decode")
if (s==0): return E(0)
if not E.is_x_coord(s^2): raise Exception("Point didn't decode")
P = E.lift_x(s^2)
t = P.xy()[1] / s
if is_odd(int(2*t/s)): P = -P
if is_odd(int(2*s^2*isoMagic/P.xy()[1])): P = -P
return P
def __eq__(self,other):
......@@ -318,16 +327,16 @@ class DecafPoint():
x,y = P.xy()
s = sqrt(x)
if s==0: return to_le(0,56)
if is_odd(int(2*y/s^2)): s = 1/s
if int(s) > (F.cardinality()-1)/2: s = -s
if is_odd(int(2*s^2*isoMagic/y)): s = 1/s
if is_odd(int(s)): s = -s
return to_le(s,56)
def _check(self):
ss = self._sage_ser(self.point)
cs = self._c_ser(self.cstruct)
if ss != cs:
print ss
print cs
print "SAGE",b64encode(ss)
print "C ",b64encode(cs)
raise Exception("Check failed!")
return True
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment