Add Moon's curve25519 using SSE2 (GH #761)

Moon's code is very fast. In fact it is so fast it broke our benchmarks. Moon's code registers 0.00 milliseconds and 0.00 megacycles/operation.
This commit is contained in:
Jeffrey Walton 2018-12-13 10:19:54 -05:00
parent 20f4d22055
commit 152ac6177c
No known key found for this signature in database
GPG Key ID: B36AB348921B1838
10 changed files with 1243 additions and 76 deletions

View File

@ -104,6 +104,7 @@ drbg.h
donna.h
donna_32.cpp
donna_64.cpp
donna_sse.cpp
dsa.cpp
dsa.h
eax.cpp

View File

@ -1438,7 +1438,11 @@ cham_simd.o : cham_simd.cpp
darn.o : darn.cpp
$(CXX) $(strip $(CXXFLAGS) $(DARN_FLAG) -c) $<
# SSE2 on i586
# SSE2 on i686
donna_sse.o : donna_sse.cpp
$(CXX) $(strip $(CXXFLAGS) $(SSE2_FLAG) -c) $<
# SSE2 on i686
sse_simd.o : sse_simd.cpp
$(CXX) $(strip $(CXXFLAGS) $(SSE2_FLAG) -c) $<

View File

@ -816,7 +816,11 @@ cham_simd.o : cham_simd.cpp
darn.o : darn.cpp
$(CXX) $(strip $(CXXFLAGS) $(DARN_FLAG) -c) $<
# SSE2 on i586
# SSE2 on i686
donna_sse.o : donna_sse.cpp
$(CXX) $(strip $(CXXFLAGS) $(SSE2_FLAG) -c) $<
# SSE2 on i686
sse_simd.o : sse_simd.cpp
$(CXX) $(strip $(CXXFLAGS) $(SSE2_FLAG) -c) $<

View File

@ -58,8 +58,8 @@ LIB_SRCS = \
cast.cpp casts.cpp cbcmac.cpp ccm.cpp chacha.cpp chacha_avx.cpp \
chacha_simd.cpp cham.cpp cham_simd.cpp channels.cpp cmac.cpp crc.cpp \
crc_simd.cpp darn.cpp default.cpp des.cpp dessp.cpp dh.cpp dh2.cpp \
dll.cpp donna_32.cpp donna_64.cpp dsa.cpp eax.cpp ec2n.cpp eccrypto.cpp \
ecp.cpp elgamal.cpp emsa2.cpp eprecomp.cpp esign.cpp files.cpp \
dll.cpp donna_32.cpp donna_64.cpp donna_sse.cpp dsa.cpp eax.cpp ec2n.cpp \
eccrypto.cpp ecp.cpp elgamal.cpp emsa2.cpp eprecomp.cpp esign.cpp files.cpp \
filters.cpp fips140.cpp fipstest.cpp gcm.cpp gcm_simd.cpp gf256.cpp \
gf2_32.cpp gf2n.cpp gfpcrypt.cpp gost.cpp gzip.cpp hc128.cpp hc256.cpp \
hex.cpp hight.cpp hmac.cpp hrtimer.cpp ida.cpp idea.cpp iterhash.cpp \
@ -88,8 +88,8 @@ LIB_OBJS = \
cast.obj casts.obj cbcmac.obj ccm.obj chacha.obj chacha_avx.obj \
chacha_simd.obj cham.obj cham_simd.obj channels.obj cmac.obj crc.obj \
crc_simd.obj darn.obj default.obj des.obj dessp.obj dh.obj dh2.obj \
dll.obj donna_32.obj donna_64.obj dsa.obj eax.obj ec2n.obj eccrypto.obj \
ecp.obj elgamal.obj emsa2.obj eprecomp.obj esign.obj files.obj \
dll.obj donna_32.obj donna_64.obj donna_sse.obj dsa.obj eax.obj ec2n.obj \
eccrypto.obj ecp.obj elgamal.obj emsa2.obj eprecomp.obj esign.obj files.obj \
filters.obj fips140.obj fipstest.obj gcm.obj gcm_simd.obj gf256.obj \
gf2_32.obj gf2n.obj gfpcrypt.obj gost.obj gzip.obj hc128.obj hc256.obj \
hex.obj hight.obj hmac.obj hrtimer.obj ida.obj idea.obj iterhash.obj \

View File

@ -215,6 +215,7 @@
</ClCompile>
<ClCompile Include="donna_32.cpp" />
<ClCompile Include="donna_64.cpp" />
<ClCompile Include="donna_sse.cpp" />
<ClCompile Include="dsa.cpp" />
<ClCompile Include="eax.cpp" />
<ClCompile Include="ec2n.cpp" />

View File

@ -146,6 +146,9 @@
<ClCompile Include="donna_64.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="donna_sse.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="dsa.cpp">
<Filter>Source Files</Filter>
</ClCompile>

51
donna.h
View File

@ -2,53 +2,6 @@
// This is a port of Adam Langley's curve25519-donna
// located at https://github.com/agl/curve25519-donna
/* Copyright 2008, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* curve25519-donna: Curve25519 elliptic curve, public key function
*
* http://code.google.com/p/curve25519-donna/
*
* Adam Langley <agl@imperialviolet.org>
*
* Derived from public domain C code by Daniel J. Bernstein <djb@cr.yp.to>
*
* More information about curve25519 can be found here
* http://cr.yp.to/ecdh.html
*
* djb's sample implementation of curve25519 is written in a special assembly
* language called qhasm and uses the floating point registers.
*
* This is, almost, a clean room reimplementation from the curve25519 paper. It
* uses many of the tricks described therein. Only the crecip function is taken
* from the sample implementation. */
#ifndef CRYPTOPP_DONNA_H
#define CRYPTOPP_DONNA_H
@ -77,6 +30,10 @@ int curve25519(byte publicKey[32], const byte secretKey[32]);
/// to <tt>sharedKey</tt>.
int curve25519(byte sharedKey[32], const byte secretKey[32], const byte othersKey[32]);
#if (CRYPTOPP_SSE2_INTRIN_AVAILABLE)
extern int curve25519_SSE2(byte sharedKey[32], const byte secretKey[32], const byte othersKey[32]);
#endif
NAMESPACE_END // Donna
NAMESPACE_END // CryptoPP

View File

@ -965,13 +965,7 @@ ANONYMOUS_NAMESPACE_END
NAMESPACE_BEGIN(CryptoPP)
NAMESPACE_BEGIN(Donna)
int curve25519(byte publicKey[32], const byte secretKey[32])
{
const byte basePoint[32] = {9};
return curve25519(publicKey, secretKey, basePoint);
}
int curve25519(byte sharedKey[32], const byte secretKey[32], const byte othersKey[32])
int curve25519_CXX(byte sharedKey[32], const byte secretKey[32], const byte othersKey[32])
{
limb bp[10], x[10], z[11], zmone[10];
byte e[32];
@ -979,18 +973,44 @@ int curve25519(byte sharedKey[32], const byte secretKey[32], const byte othersKe
for (unsigned int i = 0; i < 32; ++i)
e[i] = secretKey[i];
e[0] &= 248;
e[31] &= 127;
e[31] |= 64;
// I'd like to remove this copy/clamp but I don't
// know if an attacker can cause an information
// leak if multiply is misused.
e[0] &= 248; e[31] &= 127; e[31] |= 64;
fexpand(bp, othersKey);
cmult(x, z, e, bp);
crecip(zmone, z);
fmul(z, x, zmone);
fcontract(sharedKey, z);
return 0;
}
int curve25519(byte publicKey[32], const byte secretKey[32])
{
const byte basePoint[32] = {9};
#if (CRYPTOPP_SSE2_INTRIN_AVAILABLE)
if (HasSSE2())
return curve25519_SSE2(publicKey, secretKey, basePoint);
else
#endif
return curve25519_CXX(publicKey, secretKey, basePoint);
}
int curve25519(byte sharedKey[32], const byte secretKey[32], const byte othersKey[32])
{
#if (CRYPTOPP_SSE2_INTRIN_AVAILABLE)
if (HasSSE2())
return curve25519_SSE2(sharedKey, secretKey, othersKey);
else
#endif
return curve25519_CXX(sharedKey, secretKey, othersKey);
}
NAMESPACE_END // Donna
NAMESPACE_END // CryptoPP

View File

@ -54,6 +54,7 @@
#include "config.h"
#include "donna.h"
#include "stdcpp.h"
#include "cpu.h"
// This macro is not in a header like config.h because
// we don't want it exposed to user code. We also need
@ -482,32 +483,52 @@ ANONYMOUS_NAMESPACE_END
NAMESPACE_BEGIN(CryptoPP)
NAMESPACE_BEGIN(Donna)
int curve25519(byte publicKey[32], const byte secretKey[32])
int curve25519_CXX(byte sharedKey[32], const byte secretKey[32], const byte othersKey[32])
{
const byte basePoint[32] = {9};
return curve25519(publicKey, secretKey, basePoint);
}
limb bp[10], x[10], z[11], zmone[10];
byte e[32];
int curve25519(byte sharedKey[32], const byte secretKey[32], const byte othersKey[32])
{
limb bp[5], x[5], z[5], zmone[5];
uint8_t e[32];
for (unsigned int i = 0;i < 32;++i)
for (unsigned int i = 0; i < 32; ++i)
e[i] = secretKey[i];
e[0] &= 248;
e[31] &= 127;
e[31] |= 64;
// I'd like to remove this copy/clamp but I don't
// know if an attacker can cause an information
// leak if multiply is misused.
e[0] &= 248; e[31] &= 127; e[31] |= 64;
fexpand(bp, othersKey);
cmult(x, z, e, bp);
crecip(zmone, z);
fmul(z, x, zmone);
fcontract(sharedKey, z);
return 0;
}
int curve25519(byte publicKey[32], const byte secretKey[32])
{
const byte basePoint[32] = {9};
#if (CRYPTOPP_SSE2_INTRIN_AVAILABLE)
if (HasSSE2())
return curve25519_SSE2(publicKey, secretKey, basePoint);
else
#endif
return curve25519_CXX(publicKey, secretKey, basePoint);
}
int curve25519(byte sharedKey[32], const byte secretKey[32], const byte othersKey[32])
{
#if (CRYPTOPP_SSE2_INTRIN_AVAILABLE)
if (HasSSE2())
return curve25519_SSE2(sharedKey, secretKey, othersKey);
else
#endif
return curve25519_CXX(sharedKey, secretKey, othersKey);
}
NAMESPACE_END // Donna
NAMESPACE_END // CryptoPP

1156
donna_sse.cpp Normal file

File diff suppressed because it is too large Load Diff