1 # This is the curve25519 implementation from Matthew Dempsky's "Slownacl"
2 # library. It is in the public domain.
4 # It isn't constant-time. Don't use it except for testing.
6 # Nick got the slownacl source from:
7 # https://github.com/mdempsky/dnscurve/tree/master/slownacl
9 __all__
= ['smult_curve25519_base', 'smult_curve25519']
18 t
= expmod(b
, e
// 2, m
) ** 2 % m
19 if e
& 1: t
= (t
* b
) % m
23 return expmod(x
, P
- 2, P
)
25 # Addition and doubling formulas taken from Appendix D of "Curve25519:
26 # new Diffie-Hellman speed records".
29 (xn
,zn
), (xm
,zm
), (xd
,zd
) = n
, m
, d
30 x
= 4 * (xm
* xn
- zm
* zn
) ** 2 * zd
31 z
= 4 * (xm
* zn
- zm
* xn
) ** 2 * xd
36 x
= (xn
** 2 - zn
** 2) ** 2
37 z
= 4 * xn
* zn
* (xn
** 2 + A
* xn
* zn
+ zn
** 2)
40 def curve25519(n
, base
):
43 # f(m) evaluates to a tuple containing the mth multiple and the
44 # (m+1)th multiple of base.
46 if m
== 1: return (one
, two
)
49 return (add(pm
, pm1
, one
), double(pm1
))
50 return (double(pm
), add(pm
, pm1
, one
))
52 return (x
* inv(z
)) % P
70 if len(s
) != 32: raise ValueError('Invalid Curve25519 argument')
71 return sum(b2i(s
[i
]) << (8 * i
) for i
in range(32))
74 return ba2bs([i2b((n
>> (8 * i
)) & 255) for i
in range(32)])
82 def smult_curve25519(n
, p
):
85 return pack(curve25519(n
, p
))
87 def smult_curve25519_base(n
):
89 return pack(curve25519(n
, 9))
93 # This part I'm adding in for compatibility with the curve25519 python
99 def __init__(self
, secret
=None, seed
=None):
100 self
.private
= pack(clamp(unpack(os
.urandom(32))))
102 def get_public(self
):
103 return Public(smult_curve25519_base(self
.private
))
105 def get_shared_key(self
, public
, hashfn
):
106 return hashfn(smult_curve25519(self
.private
, public
.public
))
112 def __init__(self
, public
):