Merge pull request #263 from EinMByte/master

EdDSASigner/Verifier support, fix warnings
This commit is contained in:
EinMByte 2015-08-30 14:16:15 +02:00
commit ed96e5ede1
104 changed files with 6018 additions and 649 deletions

View File

@ -60,7 +60,7 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
)
endif()
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -undefined dynamic_lookup")
# TODO: Clang-specific flags
endif()
# Compiler flags customization (by system)

View File

@ -9,12 +9,6 @@ License
This project is licensed under the BSD 3-clause license, which can be found in the file
LICENSE in the root of the project source code.
Donations
---------
BTC: 1K7Ds6KUeR8ya287UC4rYTjvC96vXyZbDY
LTC: LKQirrYrDeTuAPnpYq5y7LVKtywfkkHi59
Requirements for Linux/FreeBSD/OSX
----------------------------------
@ -25,8 +19,7 @@ Requirements for Windows
------------------------
VS2013 (known to work with 12.0.21005.1 or newer), Boost 1.46 or newer,
crypto++ 5.62. See Win32/README-Build.txt for instructions on how to build i2pd
and its dependencies.
crypto++ 5.62.
Downloads
------------
@ -162,3 +155,8 @@ tunnels.cfg (filename of this config is subject of change):
keys = site-keys.dat
inport = 81
accesslist = <b32>[,<b32>]
Acknowledgment
--------------
The ed25519/ folder is based on the [ref10 implementation from SUPERCOP](http://bench.cr.yp.to/supercop.html).

View File

@ -284,7 +284,7 @@ namespace client
std::placeholders::_1, std::placeholders::_2));
}
void BOBCommandSession::HandleSent (const boost::system::error_code& ecode, std::size_t bytes_transferred)
void BOBCommandSession::HandleSent (const boost::system::error_code& ecode, std::size_t)
{
if (ecode)
{
@ -338,20 +338,20 @@ namespace client
Send (len);
}
void BOBCommandSession::ZapCommandHandler (const char * operand, size_t len)
void BOBCommandSession::ZapCommandHandler (const char*, size_t)
{
LogPrint (eLogDebug, "BOB: zap");
Terminate ();
}
void BOBCommandSession::QuitCommandHandler (const char * operand, size_t len)
void BOBCommandSession::QuitCommandHandler (const char*, size_t)
{
LogPrint (eLogDebug, "BOB: quit");
m_IsOpen = false;
SendReplyOK ("Bye!");
}
void BOBCommandSession::StartCommandHandler (const char * operand, size_t len)
void BOBCommandSession::StartCommandHandler (const char*, size_t)
{
LogPrint (eLogDebug, "BOB: start ", m_Nickname);
if (!m_CurrentDestination)
@ -367,7 +367,7 @@ namespace client
SendReplyOK ("tunnel starting");
}
void BOBCommandSession::StopCommandHandler (const char * operand, size_t len)
void BOBCommandSession::StopCommandHandler (const char*, size_t)
{
auto dest = m_Owner.FindDestination (m_Nickname);
if (dest)
@ -379,7 +379,7 @@ namespace client
SendReplyError ("tunnel not found");
}
void BOBCommandSession::SetNickCommandHandler (const char * operand, size_t len)
void BOBCommandSession::SetNickCommandHandler (const char * operand, size_t)
{
LogPrint (eLogDebug, "BOB: setnick ", operand);
m_Nickname = operand;
@ -388,7 +388,7 @@ namespace client
SendReplyOK (msg.c_str ());
}
void BOBCommandSession::GetNickCommandHandler (const char * operand, size_t len)
void BOBCommandSession::GetNickCommandHandler (const char * operand, size_t)
{
LogPrint (eLogDebug, "BOB: getnick ", operand);
m_CurrentDestination = m_Owner.FindDestination (operand);
@ -404,68 +404,68 @@ namespace client
SendReplyError ("tunnel not found");
}
void BOBCommandSession::NewkeysCommandHandler (const char * operand, size_t len)
void BOBCommandSession::NewkeysCommandHandler (const char*, size_t)
{
LogPrint (eLogDebug, "BOB: newkeys");
m_Keys = i2p::data::PrivateKeys::CreateRandomKeys ();
SendReplyOK (m_Keys.GetPublic ().ToBase64 ().c_str ());
}
void BOBCommandSession::SetkeysCommandHandler (const char * operand, size_t len)
void BOBCommandSession::SetkeysCommandHandler (const char * operand, size_t)
{
LogPrint (eLogDebug, "BOB: setkeys ", operand);
m_Keys.FromBase64 (operand);
SendReplyOK (m_Keys.GetPublic ().ToBase64 ().c_str ());
}
void BOBCommandSession::GetkeysCommandHandler (const char * operand, size_t len)
void BOBCommandSession::GetkeysCommandHandler (const char *, size_t)
{
LogPrint (eLogDebug, "BOB: getkeys");
SendReplyOK (m_Keys.ToBase64 ().c_str ());
}
void BOBCommandSession::GetdestCommandHandler (const char * operand, size_t len)
void BOBCommandSession::GetdestCommandHandler (const char*, size_t)
{
LogPrint (eLogDebug, "BOB: getdest");
SendReplyOK (m_Keys.GetPublic ().ToBase64 ().c_str ());
}
void BOBCommandSession::OuthostCommandHandler (const char * operand, size_t len)
void BOBCommandSession::OuthostCommandHandler (const char * operand, size_t)
{
LogPrint (eLogDebug, "BOB: outhost ", operand);
m_Address = operand;
SendReplyOK ("outhost set");
}
void BOBCommandSession::OutportCommandHandler (const char * operand, size_t len)
void BOBCommandSession::OutportCommandHandler (const char * operand, size_t)
{
LogPrint (eLogDebug, "BOB: outport ", operand);
m_OutPort = boost::lexical_cast<int>(operand);
SendReplyOK ("outbound port set");
}
void BOBCommandSession::InhostCommandHandler (const char * operand, size_t len)
void BOBCommandSession::InhostCommandHandler (const char * operand, size_t)
{
LogPrint (eLogDebug, "BOB: inhost ", operand);
m_Address = operand;
SendReplyOK ("inhost set");
}
void BOBCommandSession::InportCommandHandler (const char * operand, size_t len)
void BOBCommandSession::InportCommandHandler (const char * operand, size_t)
{
LogPrint (eLogDebug, "BOB: inport ", operand);
m_InPort = boost::lexical_cast<int>(operand);
SendReplyOK ("inbound port set");
}
void BOBCommandSession::QuietCommandHandler (const char * operand, size_t len)
void BOBCommandSession::QuietCommandHandler (const char*, size_t)
{
LogPrint (eLogDebug, "BOB: quiet");
m_IsQuiet = true;
SendReplyOK ("quiet");
}
void BOBCommandSession::LookupCommandHandler (const char * operand, size_t len)
void BOBCommandSession::LookupCommandHandler (const char * operand, size_t)
{
LogPrint (eLogDebug, "BOB: lookup ", operand);
i2p::data::IdentHash ident;
@ -493,14 +493,14 @@ namespace client
}
}
void BOBCommandSession::ClearCommandHandler (const char * operand, size_t len)
void BOBCommandSession::ClearCommandHandler (const char*, size_t)
{
LogPrint (eLogDebug, "BOB: clear");
m_Owner.DeleteDestination (m_Nickname);
SendReplyOK ("cleared");
}
void BOBCommandSession::ListCommandHandler (const char * operand, size_t len)
void BOBCommandSession::ListCommandHandler (const char*, size_t)
{
LogPrint (eLogDebug, "BOB: list");
auto& destinations = m_Owner.GetDestinations ();
@ -509,7 +509,7 @@ namespace client
SendReplyOK ("Listing done");
}
void BOBCommandSession::OptionCommandHandler (const char * operand, size_t len)
void BOBCommandSession::OptionCommandHandler (const char * operand, size_t)
{
LogPrint (eLogDebug, "BOB: option ", operand);
const char * value = strchr (operand, '=');

View File

@ -332,7 +332,7 @@ namespace client
}
void I2PServerTunnel::HandleResolve (const boost::system::error_code& ecode, boost::asio::ip::tcp::resolver::iterator it,
std::shared_ptr<boost::asio::ip::tcp::resolver> resolver)
std::shared_ptr<boost::asio::ip::tcp::resolver> )
{
if (!ecode)
{

View File

@ -133,7 +133,7 @@ namespace client
}
}
void SAMSocket::HandleHandshakeReplySent (const boost::system::error_code& ecode, std::size_t bytes_transferred)
void SAMSocket::HandleHandshakeReplySent (const boost::system::error_code& ecode, std::size_t)
{
if (ecode)
{
@ -164,7 +164,7 @@ namespace client
}
}
void SAMSocket::HandleMessageReplySent (const boost::system::error_code& ecode, std::size_t bytes_transferred, bool close)
void SAMSocket::HandleMessageReplySent (const boost::system::error_code& ecode, std::size_t, bool close)
{
if (ecode)
{
@ -258,7 +258,7 @@ namespace client
}
}
void SAMSocket::ProcessSessionCreate (char * buf, size_t len)
void SAMSocket::ProcessSessionCreate (char * buf, size_t)
{
LogPrint ("SAM session create: ", buf);
std::map<std::string, std::string> params;
@ -329,7 +329,7 @@ namespace client
SendMessageReply (m_Buffer, l2, false);
}
void SAMSocket::ProcessStreamConnect (char * buf, size_t len)
void SAMSocket::ProcessStreamConnect (char * buf, size_t)
{
LogPrint (eLogDebug, "SAM stream connect: ", buf);
std::map<std::string, std::string> params;
@ -385,7 +385,7 @@ namespace client
}
}
void SAMSocket::ProcessStreamAccept (char * buf, size_t len)
void SAMSocket::ProcessStreamAccept (char * buf, size_t)
{
LogPrint (eLogDebug, "SAM stream accept: ", buf);
std::map<std::string, std::string> params;
@ -456,7 +456,7 @@ namespace client
SendMessageReply (m_Buffer, len, false);
}
void SAMSocket::ProcessNamingLookup (char * buf, size_t len)
void SAMSocket::ProcessNamingLookup (char * buf, size_t)
{
LogPrint (eLogDebug, "SAM naming lookup: ", buf);
std::map<std::string, std::string> params;
@ -643,7 +643,7 @@ namespace client
LogPrint (eLogInfo, "SAM I2P acceptor has been reset");
}
void SAMSocket::HandleI2PDatagramReceive (const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len)
void SAMSocket::HandleI2PDatagramReceive (const i2p::data::IdentityEx& from, uint16_t, uint16_t, const uint8_t * buf, size_t len)
{
LogPrint (eLogDebug, "SAM datagram received ", len);
auto base64 = from.ToBase64 ();

View File

@ -238,7 +238,7 @@ void I2PControlSession::handleEcho(const PropertyTree& pt, Response& response)
response.setParam(I2P_CONTROL_PARAM_RESULT, echo);
}
void I2PControlSession::handleI2PControl(const PropertyTree& pt, Response& response)
void I2PControlSession::handleI2PControl(const PropertyTree&, Response&)
{
LogPrint(eLogDebug, "I2PControl I2PControl");
// TODO: implement
@ -279,9 +279,9 @@ void I2PControlSession::handleRouterManager(const PropertyTree& pt, Response& re
}
}
void I2PControlSession::handleNetworkSetting(const PropertyTree& pt, Response& response)
void I2PControlSession::handleNetworkSetting(const PropertyTree&, Response&)
{
// TODO: implement
}
void I2PControlSession::handleUptime(Response& response)
@ -351,7 +351,7 @@ void I2PControlSession::handleShutdown(Response& response)
response.setParam(I2P_CONTROL_ROUTER_MANAGER_SHUTDOWN, "");
// 1 second to make sure response has been sent
shutdownTimer.expires_from_now(boost::posix_time::seconds(1));
shutdownTimer.async_wait([](const boost::system::error_code& ecode) {
shutdownTimer.async_wait([](const boost::system::error_code&) {
Daemon.running = 0;
});
}
@ -363,7 +363,7 @@ void I2PControlSession::handleShutdownGraceful(Response& response)
LogPrint(eLogInfo, "Graceful shutdown requested. Will shutdown after ", timeout, " seconds");
response.setParam(I2P_CONTROL_ROUTER_MANAGER_SHUTDOWN_GRACEFUL, "");
shutdownTimer.expires_from_now(boost::posix_time::seconds(timeout + 1));
shutdownTimer.async_wait([](const boost::system::error_code& ecode) {
shutdownTimer.async_wait([](const boost::system::error_code&) {
Daemon.running = 0;
});
}

View File

@ -158,8 +158,8 @@ void I2PControlService::SendResponse(std::shared_ptr<boost::asio::ip::tcp::socke
);
}
void I2PControlService::HandleResponseSent(const boost::system::error_code& ecode, std::size_t bytes_transferred,
std::shared_ptr<boost::asio::ip::tcp::socket> socket, std::shared_ptr<I2PControlBuffer> buf)
void I2PControlService::HandleResponseSent(const boost::system::error_code& ecode, std::size_t,
std::shared_ptr<boost::asio::ip::tcp::socket> socket, std::shared_ptr<I2PControlBuffer>)
{
if(ecode)
LogPrint(eLogError, "I2PControl write error: ", ecode.message());

View File

@ -40,13 +40,13 @@ private:
private:
std::shared_ptr<I2PControlSession> m_Session;
bool m_IsRunning;
std::thread * m_Thread;
boost::asio::io_service m_Service;
boost::asio::ip::tcp::acceptor m_Acceptor;
std::shared_ptr<I2PControlSession> m_Session;
};
}

View File

@ -1,36 +1,79 @@
set(CORE_SRC
"transport/NTCPSession.cpp"
"transport/SSU.cpp"
"transport/SSUData.cpp"
"transport/SSUSession.cpp"
"transport/Transports.cpp"
"crypto/CryptoConst.cpp"
"crypto/aes.cpp"
"crypto/Signature.cpp"
"util/base64.cpp"
"util/util.cpp"
"util/Log.cpp"
"tunnel/TransitTunnel.cpp"
"tunnel/Tunnel.cpp"
"tunnel/TunnelGateway.cpp"
"tunnel/TunnelEndpoint.cpp"
"tunnel/TunnelPool.cpp"
"tunnel/TunnelCrypto.cpp"
"AddressBook.cpp"
"Garlic.cpp"
"I2NPProtocol.cpp"
"Identity.cpp"
"LeaseSet.cpp"
"NetDbRequests.cpp"
"NetworkDatabase.cpp"
"Profiling.cpp"
"RouterContext.cpp"
"RouterInfo.cpp"
"Streaming.cpp"
"Destination.cpp"
"Datagram.cpp"
"UPnP.cpp"
"Reseed.cpp"
"transport/NTCPSession.cpp"
"transport/SSU.cpp"
"transport/SSUData.cpp"
"transport/SSUSession.cpp"
"transport/Transports.cpp"
"crypto/CryptoConst.cpp"
"crypto/aes.cpp"
"crypto/Signature.cpp"
"crypto/EdDSA25519.cpp"
"util/base64.cpp"
"util/util.cpp"
"util/Log.cpp"
"tunnel/TransitTunnel.cpp"
"tunnel/Tunnel.cpp"
"tunnel/TunnelGateway.cpp"
"tunnel/TunnelEndpoint.cpp"
"tunnel/TunnelPool.cpp"
"tunnel/TunnelCrypto.cpp"
"AddressBook.cpp"
"Garlic.cpp"
"I2NPProtocol.cpp"
"Identity.cpp"
"LeaseSet.cpp"
"NetDbRequests.cpp"
"NetworkDatabase.cpp"
"Profiling.cpp"
"RouterContext.cpp"
"RouterInfo.cpp"
"Streaming.cpp"
"Destination.cpp"
"Datagram.cpp"
"UPnP.cpp"
"Reseed.cpp"
)
set(EDDSA_SRC
"crypto/ed25519/fe_0.cpp"
"crypto/ed25519/fe_1.cpp"
"crypto/ed25519/fe_add.cpp"
"crypto/ed25519/fe_cmov.cpp"
"crypto/ed25519/fe_copy.cpp"
"crypto/ed25519/fe_frombytes.cpp"
"crypto/ed25519/fe_invert.cpp"
"crypto/ed25519/fe_isnegative.cpp"
"crypto/ed25519/fe_isnonzero.cpp"
"crypto/ed25519/fe_mul.cpp"
"crypto/ed25519/fe_neg.cpp"
"crypto/ed25519/fe_pow22523.cpp"
"crypto/ed25519/fe_sq2.cpp"
"crypto/ed25519/fe_sq.cpp"
"crypto/ed25519/fe_sub.cpp"
"crypto/ed25519/fe_tobytes.cpp"
"crypto/ed25519/ge_add.cpp"
"crypto/ed25519/ge_double_scalarmult.cpp"
"crypto/ed25519/ge_frombytes.cpp"
"crypto/ed25519/ge_madd.cpp"
"crypto/ed25519/ge_msub.cpp"
"crypto/ed25519/ge_p1p1_to_p2.cpp"
"crypto/ed25519/ge_p1p1_to_p3.cpp"
"crypto/ed25519/ge_p2_0.cpp"
"crypto/ed25519/ge_p2_dbl.cpp"
"crypto/ed25519/ge_p3_0.cpp"
"crypto/ed25519/ge_p3_dbl.cpp"
"crypto/ed25519/ge_p3_tobytes.cpp"
"crypto/ed25519/ge_p3_to_cached.cpp"
"crypto/ed25519/ge_p3_to_p2.cpp"
"crypto/ed25519/ge_precomp_0.cpp"
"crypto/ed25519/ge_scalarmult_base.cpp"
"crypto/ed25519/ge_sub.cpp"
"crypto/ed25519/ge_tobytes.cpp"
"crypto/ed25519/keypair.cpp"
"crypto/ed25519/open.cpp"
"crypto/ed25519/sc_muladd.cpp"
"crypto/ed25519/sc_reduce.cpp"
"crypto/ed25519/sign.cpp"
)
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
@ -39,9 +82,13 @@ endif()
include_directories(".")
set(EDDSA_LIB "ed25519-ref10")
add_subdirectory(crypto/ed25519)
# Library building
if(WITH_LIBRARY)
add_library(${CORE_NAME} ${CORE_SRC})
add_library(${CORE_NAME} ${CORE_SRC} ${EDDSA_SRC})
target_link_libraries(
${CORE_NAME} ${Boost_LIBRARIES} ${CRYPTO++_LIBRARIES}
)

View File

@ -225,7 +225,7 @@ namespace client
m_Service.post (std::bind (&ClientDestination::HandleDeliveryStatusMessage, this, msg));
}
void ClientDestination::HandleI2NPMessage (const uint8_t * buf, size_t len, std::shared_ptr<i2p::tunnel::InboundTunnel> from)
void ClientDestination::HandleI2NPMessage (const uint8_t * buf, size_t, std::shared_ptr<i2p::tunnel::InboundTunnel> from)
{
uint8_t typeID = buf[I2NP_HEADER_TYPEID_OFFSET];
switch (typeID)
@ -303,7 +303,7 @@ namespace client
}
}
void ClientDestination::HandleDatabaseSearchReplyMessage (const uint8_t * buf, size_t len)
void ClientDestination::HandleDatabaseSearchReplyMessage (const uint8_t * buf, size_t)
{
i2p::data::IdentHash key (buf);
int num = buf[32]; // num
@ -417,7 +417,7 @@ namespace client
}
}
void ClientDestination::HandleDataMessage (const uint8_t * buf, size_t len)
void ClientDestination::HandleDataMessage (const uint8_t * buf, size_t)
{
uint32_t length = bufbe32toh (buf);
buf += 4;

View File

@ -5,6 +5,7 @@
#include <cryptopp/dsa.h>
#include "util/base64.h"
#include "crypto/CryptoConst.h"
#include "crypto/Signature.h"
#include "crypto/ElGamal.h"
#include "RouterContext.h"
#include "Identity.h"
@ -22,7 +23,7 @@ namespace data
return *this;
}
size_t Identity::FromBuffer (const uint8_t * buf, size_t len)
size_t Identity::FromBuffer (const uint8_t * buf, size_t)
{
memcpy (publicKey, buf, DEFAULT_IDENTITY_SIZE);
return DEFAULT_IDENTITY_SIZE;
@ -226,7 +227,7 @@ namespace data
return GetFullLen ();
}
size_t IdentityEx::ToBuffer (uint8_t * buf, size_t len) const
size_t IdentityEx::ToBuffer (uint8_t * buf, size_t) const
{
memcpy (buf, &m_StandardIdentity, DEFAULT_IDENTITY_SIZE);
if (m_ExtendedLen > 0 && m_ExtendedBuffer)
@ -370,6 +371,7 @@ namespace data
delete verifier;
}
PrivateKeys& PrivateKeys::operator=(const Keys& keys)
{
m_Public = Identity (keys);
@ -391,6 +393,11 @@ namespace data
CreateSigner ();
return *this;
}
PrivateKeys::~PrivateKeys()
{
delete m_Signer;
}
size_t PrivateKeys::FromBuffer (const uint8_t * buf, size_t len)
{

View File

@ -7,12 +7,16 @@
#include <memory>
#include "util/base64.h"
#include "crypto/ElGamal.h"
#include "crypto/Signature.h"
namespace i2p
{
namespace data
{
namespace i2p {
// Forward declaration to avoid include
namespace crypto {
class Signer;
class Verifier;
}
namespace data {
template<int sz>
class Tag
{
@ -183,7 +187,7 @@ namespace data
PrivateKeys (const Keys& keys): m_Signer (nullptr) { *this = keys; };
PrivateKeys& operator=(const Keys& keys);
PrivateKeys& operator=(const PrivateKeys& other);
~PrivateKeys () { delete m_Signer; };
~PrivateKeys ();
const IdentityEx& GetPublic () const { return m_Public; };
const uint8_t * GetPrivateKey () const { return m_PrivateKey; };

View File

@ -16,6 +16,7 @@
#include "util/Log.h"
#include "Identity.h"
#include "crypto/CryptoConst.h"
#include "crypto/Signature.h"
#include "NetworkDatabase.h"
#include "util/util.h"

View File

@ -294,7 +294,7 @@ namespace i2p
return i2p::tunnel::tunnels.GetExploratoryPool ();
}
void RouterContext::HandleI2NPMessage (const uint8_t * buf, size_t len, std::shared_ptr<i2p::tunnel::InboundTunnel> from)
void RouterContext::HandleI2NPMessage (const uint8_t * buf, size_t, std::shared_ptr<i2p::tunnel::InboundTunnel> from)
{
i2p::HandleI2NPMessage (CreateI2NPMessage (buf, GetI2NPMessageLength (buf), from));
}

View File

@ -692,7 +692,7 @@ namespace stream
}
}
void Stream::HandleAckSendTimer (const boost::system::error_code& ecode)
void Stream::HandleAckSendTimer (const boost::system::error_code&)
{
if (m_IsAckSendScheduled)
{

View File

@ -3,35 +3,34 @@
#include <cryptopp/integer.h>
namespace i2p
{
namespace crypto
{
struct CryptoConstants
{
// DH/ElGamal
const CryptoPP::Integer elgp;
const CryptoPP::Integer elgg;
namespace i2p {
namespace crypto {
// DSA
const CryptoPP::Integer dsap;
const CryptoPP::Integer dsaq;
const CryptoPP::Integer dsag;
};
const CryptoConstants& GetCryptoConstants ();
// DH/ElGamal
#define elgp GetCryptoConstants ().elgp
#define elgg GetCryptoConstants ().elgg
struct CryptoConstants {
// DH/ElGamal
const CryptoPP::Integer elgp;
const CryptoPP::Integer elgg;
// DSA
#define dsap GetCryptoConstants ().dsap
#define dsaq GetCryptoConstants ().dsaq
#define dsag GetCryptoConstants ().dsag
const CryptoPP::Integer dsap;
const CryptoPP::Integer dsaq;
const CryptoPP::Integer dsag;
};
// RSA
const int rsae = 65537;
const CryptoConstants& GetCryptoConstants ();
// DH/ElGamal
#define elgp GetCryptoConstants ().elgp
#define elgg GetCryptoConstants ().elgg
// DSA
#define dsap GetCryptoConstants ().dsap
#define dsaq GetCryptoConstants ().dsaq
#define dsag GetCryptoConstants ().dsag
// RSA
const int rsae = 65537;
}
}

View File

@ -0,0 +1,57 @@
#include "EdDSA25519.h"
#include "ed25519/ed25519_ref10.h"
#include <cstring>
namespace i2p {
namespace crypto {
EDDSA25519Verifier::EDDSA25519Verifier(const uint8_t* signingKey)
{
std::memcpy(m_PublicKey, signingKey, EDDSA25519_PUBLIC_KEY_LENGTH);
}
bool EDDSA25519Verifier::Verify(const uint8_t* buf, size_t len, const uint8_t* signature) const
{
return ed25519_ref10_open(signature, buf, len, m_PublicKey) >= 0;
}
size_t EDDSA25519Verifier::GetPublicKeyLen() const
{
return EDDSA25519_PUBLIC_KEY_LENGTH;
}
size_t EDDSA25519Verifier::GetSignatureLen() const
{
return EDDSA25519_SIGNATURE_LENGTH;
}
EDDSA25519Signer::EDDSA25519Signer(const uint8_t* signingPrivateKey, const uint8_t* signingPublicKey)
{
std::memcpy(m_PrivateKey, signingPrivateKey, EDDSA25519_PRIVATE_KEY_LENGTH);
std::memcpy(m_PublicKey, signingPublicKey, EDDSA25519_PUBLIC_KEY_LENGTH);
}
EDDSA25519Signer::EDDSA25519Signer(const uint8_t* signingPrivateKey)
{
std::memcpy(m_PrivateKey, signingPrivateKey, EDDSA25519_PRIVATE_KEY_LENGTH);
ed25519_ref10_pubkey(m_PublicKey, m_PrivateKey);
}
void EDDSA25519Signer::Sign(CryptoPP::RandomNumberGenerator&, const uint8_t* buf, int len, uint8_t* signature) const
{
ed25519_ref10_sign(signature, buf, len, m_PrivateKey, m_PublicKey);
}
void CreateEDDSARandomKeys(CryptoPP::RandomNumberGenerator& rnd, uint8_t* privateKey,
uint8_t* publicKey)
{
rnd.GenerateBlock(privateKey, EDDSA25519_PRIVATE_KEY_LENGTH);
ed25519_ref10_pubkey(publicKey, privateKey);
}
}
}

58
core/crypto/EdDSA25519.h Normal file
View File

@ -0,0 +1,58 @@
#ifndef EDDSA25519_H__
#define EDDSA25519_H__
#include "SignatureBase.h"
namespace i2p {
namespace crypto {
// EdDSA
const size_t EDDSA25519_PUBLIC_KEY_LENGTH = 32;
const size_t EDDSA25519_SIGNATURE_LENGTH = 64;
const size_t EDDSA25519_PRIVATE_KEY_LENGTH = 32;
class EDDSA25519Verifier : public Verifier {
public:
EDDSA25519Verifier(const uint8_t* signingKey);
bool Verify(const uint8_t* buf, size_t len, const uint8_t* signature) const;
size_t GetPublicKeyLen() const;
size_t GetSignatureLen() const;
private:
uint8_t m_PublicKey[EDDSA25519_PUBLIC_KEY_LENGTH];
};
class EDDSA25519Signer : public Signer {
public:
/**
* Construct from a key pair.
*/
EDDSA25519Signer(const uint8_t* signingPrivateKey, const uint8_t* signingPublicKey);
/**
* Construct from a private key.
* The corresponding public key will be computed from it.
*/
EDDSA25519Signer(const uint8_t* signingPrivateKey);
/**
* @todo do not pass random number generator, EdDSA does not require a random
* source
*/
void Sign(CryptoPP::RandomNumberGenerator&, const uint8_t* buf, int len, uint8_t* signature) const;
uint8_t m_PrivateKey[EDDSA25519_PRIVATE_KEY_LENGTH];
uint8_t m_PublicKey[EDDSA25519_PUBLIC_KEY_LENGTH];
};
void CreateEDDSARandomKeys(CryptoPP::RandomNumberGenerator& rnd, uint8_t* privateKey,
uint8_t* publicKey);
}
}
#endif // EDDSA25519_H__

View File

@ -4,118 +4,35 @@
#include "util/Log.h"
#include "Signature.h"
namespace i2p
namespace i2p {
namespace crypto {
DSASigner::DSASigner(const uint8_t * signingPrivateKey)
{
namespace crypto
{
class Ed25519
{
public:
Ed25519 ()
{
q = CryptoPP::Integer::Power2 (255) - CryptoPP::Integer (19); // 2^255-19
l = CryptoPP::Integer::Power2 (252) + CryptoPP::Integer ("27742317777372353535851937790883648493");
// 2^252 + 27742317777372353535851937790883648493
d = CryptoPP::Integer (-121665) * CryptoPP::Integer (121666).InverseMod (q); // -121665/121666
I = a_exp_b_mod_c (CryptoPP::Integer::Two (), (q - CryptoPP::Integer::One ()).DividedBy (4), q);
B = DecodePoint (CryptoPP::Integer (4)*CryptoPP::Integer (5).InverseMod (q));
}
CryptoPP::ECP::Point DecodePublicKey (const uint8_t * key) const
{
return DecodePoint (CryptoPP::Integer (key, 32));
}
CryptoPP::ECP::Point GeneratePublicKey (const uint8_t * privateKey) const
{
return Mul (B, CryptoPP::Integer (privateKey, 32));
}
private:
CryptoPP::ECP::Point Sum (const CryptoPP::ECP::Point& p1, const CryptoPP::ECP::Point& p2) const
{
CryptoPP::Integer m = d*p1.x*p2.x*p1.y*p2.y,
x = a_times_b_mod_c (p1.x*p2.y + p2.x*p1.y, (CryptoPP::Integer::One() + m).InverseMod (q), q),
y = a_times_b_mod_c (p1.y*p2.y + p1.x*p2.x, (CryptoPP::Integer::One() - m).InverseMod (q), q);
return CryptoPP::ECP::Point {x, y};
}
CryptoPP::ECP::Point Mul (const CryptoPP::ECP::Point& p, const CryptoPP::Integer& e) const
{
CryptoPP::ECP::Point res {0, 1};
if (!e.IsZero ())
{
auto bitCount = e.BitCount ();
for (int i = bitCount - 1; i >= 0; i--)
{
res = Sum (res, res);
if (e.GetBit (i)) res = Sum (res, p);
}
}
return res;
}
bool IsOnCurve (const CryptoPP::ECP::Point& p) const
{
auto x2 = p.x.Squared(), y2 = p.y.Squared ();
return (y2 - x2 - CryptoPP::Integer::One() - d*x2*y2).Modulo (q).IsZero ();
}
CryptoPP::Integer RecoverX (const CryptoPP::Integer& y) const
{
auto y2 = y.Squared ();
auto xx = (y2 - CryptoPP::Integer::One())*(d*y2 + CryptoPP::Integer::One()).InverseMod (q);
auto x = a_exp_b_mod_c (xx, (q + CryptoPP::Integer (3)).DividedBy (8), q);
if (!(x.Squared () - xx).Modulo (q).IsZero ())
x = a_times_b_mod_c (x, I, q);
if (x.IsOdd ()) x = q - x;
return x;
}
CryptoPP::ECP::Point DecodePoint (const CryptoPP::Integer& y) const
{
auto x = RecoverX (y);
CryptoPP::ECP::Point p {x, y};
if (!IsOnCurve (p))
{
LogPrint (eLogError, "Decoded point is not on 25519");
return CryptoPP::ECP::Point {0, 1};
}
return p;
}
private:
CryptoPP::Integer q, l, d, I;
CryptoPP::ECP::Point B; // base point
};
static std::unique_ptr<Ed25519> g_Ed25519;
std::unique_ptr<Ed25519>& GetEd25519 ()
{
if (!g_Ed25519)
g_Ed25519.reset (new Ed25519 ());
return g_Ed25519;
}
EDDSA25519Verifier::EDDSA25519Verifier (const uint8_t * signingKey):
m_PublicKey (GetEd25519 ()->DecodePublicKey (signingKey))
{
}
bool EDDSA25519Verifier::Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const
{
return true; // TODO:
}
void EDDSA25519Signer::Sign (CryptoPP::RandomNumberGenerator& rnd, const uint8_t * buf, int len, uint8_t * signature) const
{
// TODO
}
}
m_PrivateKey.Initialize(
dsap, dsaq, dsag,
CryptoPP::Integer(signingPrivateKey, DSA_PRIVATE_KEY_LENGTH)
);
}
void DSASigner::Sign(CryptoPP::RandomNumberGenerator& rnd, const uint8_t * buf,
int len, uint8_t * signature) const
{
CryptoPP::DSA::Signer signer(m_PrivateKey);
signer.SignMessage(rnd, buf, len, signature);
}
void CreateDSARandomKeys(CryptoPP::RandomNumberGenerator& rnd,
uint8_t* signingPrivateKey, uint8_t* signingPublicKey)
{
CryptoPP::DSA::PrivateKey privateKey;
CryptoPP::DSA::PublicKey publicKey;
privateKey.Initialize(rnd, dsap, dsaq, dsag);
privateKey.MakePublicKey(publicKey);
privateKey.GetPrivateExponent().Encode(signingPrivateKey, DSA_PRIVATE_KEY_LENGTH);
publicKey.GetPublicElement().Encode(signingPublicKey, DSA_PUBLIC_KEY_LENGTH);
}
} // crypto
} // i2p

View File

@ -9,437 +9,350 @@
#include <cryptopp/osrng.h>
#include <cryptopp/eccrypto.h>
#include "CryptoConst.h"
#include "SignatureBase.h"
namespace i2p
{
namespace crypto
{
class Verifier
#include "EdDSA25519.h"
namespace i2p {
namespace crypto {
const size_t DSA_PUBLIC_KEY_LENGTH = 128;
const size_t DSA_SIGNATURE_LENGTH = 40;
const size_t DSA_PRIVATE_KEY_LENGTH = DSA_SIGNATURE_LENGTH/2;
class DSAVerifier: public Verifier {
public:
DSAVerifier(const uint8_t * signingKey)
{
public:
virtual ~Verifier () {};
virtual bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const = 0;
virtual size_t GetPublicKeyLen () const = 0;
virtual size_t GetSignatureLen () const = 0;
virtual size_t GetPrivateKeyLen () const { return GetSignatureLen ()/2; };
};
class Signer
{
public:
virtual ~Signer () {};
virtual void Sign (CryptoPP::RandomNumberGenerator& rnd, const uint8_t * buf, int len, uint8_t * signature) const = 0;
};
const size_t DSA_PUBLIC_KEY_LENGTH = 128;
const size_t DSA_SIGNATURE_LENGTH = 40;
const size_t DSA_PRIVATE_KEY_LENGTH = DSA_SIGNATURE_LENGTH/2;
class DSAVerifier: public Verifier
{
public:
DSAVerifier (const uint8_t * signingKey)
{
m_PublicKey.Initialize (dsap, dsaq, dsag, CryptoPP::Integer (signingKey, DSA_PUBLIC_KEY_LENGTH));
}
bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const
{
CryptoPP::DSA::Verifier verifier (m_PublicKey);
return verifier.VerifyMessage (buf, len, signature, DSA_SIGNATURE_LENGTH);
}
size_t GetPublicKeyLen () const { return DSA_PUBLIC_KEY_LENGTH; };
size_t GetSignatureLen () const { return DSA_SIGNATURE_LENGTH; };
private:
CryptoPP::DSA::PublicKey m_PublicKey;
};
class DSASigner: public Signer
{
public:
DSASigner (const uint8_t * signingPrivateKey)
{
m_PrivateKey.Initialize (dsap, dsaq, dsag, CryptoPP::Integer (signingPrivateKey, DSA_PRIVATE_KEY_LENGTH));
}
void Sign (CryptoPP::RandomNumberGenerator& rnd, const uint8_t * buf, int len, uint8_t * signature) const
{
CryptoPP::DSA::Signer signer (m_PrivateKey);
signer.SignMessage (rnd, buf, len, signature);
}
private:
CryptoPP::DSA::PrivateKey m_PrivateKey;
};
inline void CreateDSARandomKeys (CryptoPP::RandomNumberGenerator& rnd, uint8_t * signingPrivateKey, uint8_t * signingPublicKey)
{
CryptoPP::DSA::PrivateKey privateKey;
CryptoPP::DSA::PublicKey publicKey;
privateKey.Initialize (rnd, dsap, dsaq, dsag);
privateKey.MakePublicKey (publicKey);
privateKey.GetPrivateExponent ().Encode (signingPrivateKey, DSA_PRIVATE_KEY_LENGTH);
publicKey.GetPublicElement ().Encode (signingPublicKey, DSA_PUBLIC_KEY_LENGTH);
}
template<typename Hash, size_t keyLen>
class ECDSAVerifier: public Verifier
{
public:
template<typename Curve>
ECDSAVerifier (Curve curve, const uint8_t * signingKey)
{
m_PublicKey.Initialize (curve,
CryptoPP::ECP::Point (CryptoPP::Integer (signingKey, keyLen/2),
CryptoPP::Integer (signingKey + keyLen/2, keyLen/2)));
}
bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const
{
typename CryptoPP::ECDSA<CryptoPP::ECP, Hash>::Verifier verifier (m_PublicKey);
return verifier.VerifyMessage (buf, len, signature, keyLen); // signature length
}
size_t GetPublicKeyLen () const { return keyLen; };
size_t GetSignatureLen () const { return keyLen; }; // signature length = key length
private:
typename CryptoPP::ECDSA<CryptoPP::ECP, Hash>::PublicKey m_PublicKey;
};
template<typename Hash>
class ECDSASigner: public Signer
{
public:
template<typename Curve>
ECDSASigner (Curve curve, const uint8_t * signingPrivateKey, size_t keyLen)
{
m_PrivateKey.Initialize (curve, CryptoPP::Integer (signingPrivateKey, keyLen/2)); // private key length
}
void Sign (CryptoPP::RandomNumberGenerator& rnd, const uint8_t * buf, int len, uint8_t * signature) const
{
typename CryptoPP::ECDSA<CryptoPP::ECP, Hash>::Signer signer (m_PrivateKey);
signer.SignMessage (rnd, buf, len, signature);
}
private:
typename CryptoPP::ECDSA<CryptoPP::ECP, Hash>::PrivateKey m_PrivateKey;
};
template<typename Hash, typename Curve>
inline void CreateECDSARandomKeys (CryptoPP::RandomNumberGenerator& rnd, Curve curve,
size_t keyLen, uint8_t * signingPrivateKey, uint8_t * signingPublicKey)
{
typename CryptoPP::ECDSA<CryptoPP::ECP, Hash>::PrivateKey privateKey;
typename CryptoPP::ECDSA<CryptoPP::ECP, Hash>::PublicKey publicKey;
privateKey.Initialize (rnd, curve);
privateKey.MakePublicKey (publicKey);
privateKey.GetPrivateExponent ().Encode (signingPrivateKey, keyLen/2);
auto q = publicKey.GetPublicElement ();
q.x.Encode (signingPublicKey, keyLen/2);
q.y.Encode (signingPublicKey + keyLen/2, keyLen/2);
}
// ECDSA_SHA256_P256
const size_t ECDSAP256_KEY_LENGTH = 64;
class ECDSAP256Verifier: public ECDSAVerifier<CryptoPP::SHA256, ECDSAP256_KEY_LENGTH>
{
public:
ECDSAP256Verifier (const uint8_t * signingKey):
ECDSAVerifier (CryptoPP::ASN1::secp256r1(), signingKey)
{
}
};
class ECDSAP256Signer: public ECDSASigner<CryptoPP::SHA256>
{
public:
ECDSAP256Signer (const uint8_t * signingPrivateKey):
ECDSASigner (CryptoPP::ASN1::secp256r1(), signingPrivateKey, ECDSAP256_KEY_LENGTH)
{
}
};
inline void CreateECDSAP256RandomKeys (CryptoPP::RandomNumberGenerator& rnd, uint8_t * signingPrivateKey, uint8_t * signingPublicKey)
{
CreateECDSARandomKeys<CryptoPP::SHA256> (rnd, CryptoPP::ASN1::secp256r1(), ECDSAP256_KEY_LENGTH, signingPrivateKey, signingPublicKey);
}
// ECDSA_SHA384_P384
const size_t ECDSAP384_KEY_LENGTH = 96;
class ECDSAP384Verifier: public ECDSAVerifier<CryptoPP::SHA384, ECDSAP384_KEY_LENGTH>
{
public:
ECDSAP384Verifier (const uint8_t * signingKey):
ECDSAVerifier (CryptoPP::ASN1::secp384r1(), signingKey)
{
}
};
class ECDSAP384Signer: public ECDSASigner<CryptoPP::SHA384>
{
public:
ECDSAP384Signer (const uint8_t * signingPrivateKey):
ECDSASigner (CryptoPP::ASN1::secp384r1(), signingPrivateKey, ECDSAP384_KEY_LENGTH)
{
}
};
inline void CreateECDSAP384RandomKeys (CryptoPP::RandomNumberGenerator& rnd, uint8_t * signingPrivateKey, uint8_t * signingPublicKey)
{
CreateECDSARandomKeys<CryptoPP::SHA384> (rnd, CryptoPP::ASN1::secp384r1(), ECDSAP384_KEY_LENGTH, signingPrivateKey, signingPublicKey);
}
// ECDSA_SHA512_P521
const size_t ECDSAP521_KEY_LENGTH = 132;
class ECDSAP521Verifier: public ECDSAVerifier<CryptoPP::SHA512, ECDSAP521_KEY_LENGTH>
{
public:
ECDSAP521Verifier (const uint8_t * signingKey):
ECDSAVerifier (CryptoPP::ASN1::secp521r1(), signingKey)
{
}
};
class ECDSAP521Signer: public ECDSASigner<CryptoPP::SHA512>
{
public:
ECDSAP521Signer (const uint8_t * signingPrivateKey):
ECDSASigner (CryptoPP::ASN1::secp521r1(), signingPrivateKey, ECDSAP521_KEY_LENGTH)
{
}
};
inline void CreateECDSAP521RandomKeys (CryptoPP::RandomNumberGenerator& rnd, uint8_t * signingPrivateKey, uint8_t * signingPublicKey)
{
CreateECDSARandomKeys<CryptoPP::SHA512> (rnd, CryptoPP::ASN1::secp521r1(), ECDSAP521_KEY_LENGTH, signingPrivateKey, signingPublicKey);
m_PublicKey.Initialize(dsap, dsaq, dsag, CryptoPP::Integer(signingKey, DSA_PUBLIC_KEY_LENGTH));
}
// RSA
template<typename Hash, size_t keyLen>
class RSAVerifier: public Verifier
bool Verify(const uint8_t * buf, size_t len, const uint8_t * signature) const
{
public:
RSAVerifier (const uint8_t * signingKey)
{
m_PublicKey.Initialize (CryptoPP::Integer (signingKey, keyLen), CryptoPP::Integer (rsae));
}
bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const
{
typename CryptoPP::RSASS<CryptoPP::PKCS1v15, Hash>::Verifier verifier (m_PublicKey);
return verifier.VerifyMessage (buf, len, signature, keyLen); // signature length
}
size_t GetPublicKeyLen () const { return keyLen; }
size_t GetSignatureLen () const { return keyLen; }
size_t GetPrivateKeyLen () const { return GetSignatureLen ()*2; };
private:
CryptoPP::RSA::PublicKey m_PublicKey;
};
template<typename Hash>
class RSASigner: public Signer
{
public:
RSASigner (const uint8_t * signingPrivateKey, size_t keyLen)
{
m_PrivateKey.Initialize (CryptoPP::Integer (signingPrivateKey, keyLen/2),
rsae,
CryptoPP::Integer (signingPrivateKey + keyLen/2, keyLen/2));
}
void Sign (CryptoPP::RandomNumberGenerator& rnd, const uint8_t * buf, int len, uint8_t * signature) const
{
typename CryptoPP::RSASS<CryptoPP::PKCS1v15, Hash>::Signer signer (m_PrivateKey);
signer.SignMessage (rnd, buf, len, signature);
}
private:
CryptoPP::RSA::PrivateKey m_PrivateKey;
};
inline void CreateRSARandomKeys (CryptoPP::RandomNumberGenerator& rnd,
size_t publicKeyLen, uint8_t * signingPrivateKey, uint8_t * signingPublicKey)
{
CryptoPP::RSA::PrivateKey privateKey;
privateKey.Initialize (rnd, publicKeyLen*8, rsae);
privateKey.GetModulus ().Encode (signingPrivateKey, publicKeyLen);
privateKey.GetPrivateExponent ().Encode (signingPrivateKey + publicKeyLen, publicKeyLen);
privateKey.GetModulus ().Encode (signingPublicKey, publicKeyLen);
CryptoPP::DSA::Verifier verifier(m_PublicKey);
return verifier.VerifyMessage(buf, len, signature, DSA_SIGNATURE_LENGTH);
}
size_t GetPublicKeyLen() const { return DSA_PUBLIC_KEY_LENGTH; };
size_t GetSignatureLen() const { return DSA_SIGNATURE_LENGTH; };
private:
CryptoPP::DSA::PublicKey m_PublicKey;
};
class DSASigner : public Signer {
public:
DSASigner(const uint8_t * signingPrivateKey);
void Sign(CryptoPP::RandomNumberGenerator& rnd, const uint8_t * buf, int len,
uint8_t* signature) const;
private:
CryptoPP::DSA::PrivateKey m_PrivateKey;
};
void CreateDSARandomKeys(CryptoPP::RandomNumberGenerator& rnd, uint8_t* signingPrivateKey,
uint8_t* signingPublicKey);
template<typename Hash, size_t keyLen>
class ECDSAVerifier: public Verifier {
public:
template<typename Curve>
ECDSAVerifier(Curve curve, const uint8_t * signingKey)
{
m_PublicKey.Initialize(curve,
CryptoPP::ECP::Point(CryptoPP::Integer(signingKey, keyLen/2),
CryptoPP::Integer(signingKey + keyLen/2, keyLen/2)));
}
bool Verify(const uint8_t * buf, size_t len, const uint8_t * signature) const
{
typename CryptoPP::ECDSA<CryptoPP::ECP, Hash>::Verifier verifier(m_PublicKey);
return verifier.VerifyMessage(buf, len, signature, keyLen); // signature length
}
size_t GetPublicKeyLen() const { return keyLen; };
size_t GetSignatureLen() const { return keyLen; }; // signature length = key length
private:
typename CryptoPP::ECDSA<CryptoPP::ECP, Hash>::PublicKey m_PublicKey;
};
template<typename Hash>
class ECDSASigner: public Signer {
public:
template<typename Curve>
ECDSASigner(Curve curve, const uint8_t * signingPrivateKey, size_t keyLen)
{
m_PrivateKey.Initialize(curve, CryptoPP::Integer(signingPrivateKey, keyLen/2)); // private key length
}
void Sign(CryptoPP::RandomNumberGenerator& rnd, const uint8_t * buf, int len, uint8_t * signature) const
{
typename CryptoPP::ECDSA<CryptoPP::ECP, Hash>::Signer signer(m_PrivateKey);
signer.SignMessage(rnd, buf, len, signature);
}
private:
typename CryptoPP::ECDSA<CryptoPP::ECP, Hash>::PrivateKey m_PrivateKey;
};
template<typename Hash, typename Curve>
inline void CreateECDSARandomKeys(CryptoPP::RandomNumberGenerator& rnd, Curve curve,
size_t keyLen, uint8_t * signingPrivateKey, uint8_t * signingPublicKey)
{
typename CryptoPP::ECDSA<CryptoPP::ECP, Hash>::PrivateKey privateKey;
typename CryptoPP::ECDSA<CryptoPP::ECP, Hash>::PublicKey publicKey;
privateKey.Initialize(rnd, curve);
privateKey.MakePublicKey(publicKey);
privateKey.GetPrivateExponent().Encode(signingPrivateKey, keyLen/2);
auto q = publicKey.GetPublicElement();
q.x.Encode(signingPublicKey, keyLen/2);
q.y.Encode(signingPublicKey + keyLen/2, keyLen/2);
}
// ECDSA_SHA256_P256
const size_t ECDSAP256_KEY_LENGTH = 64;
struct ECDSAP256Verifier: public ECDSAVerifier<CryptoPP::SHA256, ECDSAP256_KEY_LENGTH> {
ECDSAP256Verifier(const uint8_t * signingKey)
: ECDSAVerifier(CryptoPP::ASN1::secp256r1(), signingKey) { }
};
struct ECDSAP256Signer: public ECDSASigner<CryptoPP::SHA256> {
ECDSAP256Signer(const uint8_t * signingPrivateKey)
: ECDSASigner(CryptoPP::ASN1::secp256r1(), signingPrivateKey, ECDSAP256_KEY_LENGTH) { }
};
inline void CreateECDSAP256RandomKeys(CryptoPP::RandomNumberGenerator& rnd, uint8_t * signingPrivateKey, uint8_t * signingPublicKey)
{
CreateECDSARandomKeys<CryptoPP::SHA256>(rnd, CryptoPP::ASN1::secp256r1(), ECDSAP256_KEY_LENGTH, signingPrivateKey, signingPublicKey);
}
// ECDSA_SHA384_P384
const size_t ECDSAP384_KEY_LENGTH = 96;
class ECDSAP384Verifier: public ECDSAVerifier<CryptoPP::SHA384, ECDSAP384_KEY_LENGTH> {
public:
ECDSAP384Verifier(const uint8_t * signingKey):
ECDSAVerifier(CryptoPP::ASN1::secp384r1(), signingKey)
{
}
};
class ECDSAP384Signer: public ECDSASigner<CryptoPP::SHA384> {
public:
ECDSAP384Signer(const uint8_t * signingPrivateKey):
ECDSASigner(CryptoPP::ASN1::secp384r1(), signingPrivateKey, ECDSAP384_KEY_LENGTH)
{
}
};
inline void CreateECDSAP384RandomKeys(CryptoPP::RandomNumberGenerator& rnd, uint8_t * signingPrivateKey, uint8_t * signingPublicKey)
{
CreateECDSARandomKeys<CryptoPP::SHA384>(rnd, CryptoPP::ASN1::secp384r1(), ECDSAP384_KEY_LENGTH, signingPrivateKey, signingPublicKey);
}
// ECDSA_SHA512_P521
const size_t ECDSAP521_KEY_LENGTH = 132;
class ECDSAP521Verifier: public ECDSAVerifier<CryptoPP::SHA512, ECDSAP521_KEY_LENGTH> {
public:
ECDSAP521Verifier(const uint8_t * signingKey):
ECDSAVerifier(CryptoPP::ASN1::secp521r1(), signingKey)
{
}
};
class ECDSAP521Signer: public ECDSASigner<CryptoPP::SHA512> {
public:
ECDSAP521Signer(const uint8_t * signingPrivateKey):
ECDSASigner(CryptoPP::ASN1::secp521r1(), signingPrivateKey, ECDSAP521_KEY_LENGTH)
{
}
};
inline void CreateECDSAP521RandomKeys(CryptoPP::RandomNumberGenerator& rnd, uint8_t * signingPrivateKey, uint8_t * signingPublicKey)
{
CreateECDSARandomKeys<CryptoPP::SHA512>(rnd, CryptoPP::ASN1::secp521r1(), ECDSAP521_KEY_LENGTH, signingPrivateKey, signingPublicKey);
}
// RSA
template<typename Hash, size_t keyLen>
class RSAVerifier: public Verifier {
public:
RSAVerifier(const uint8_t * signingKey)
{
m_PublicKey.Initialize(CryptoPP::Integer(signingKey, keyLen), CryptoPP::Integer(rsae));
}
bool Verify(const uint8_t * buf, size_t len, const uint8_t * signature) const
{
typename CryptoPP::RSASS<CryptoPP::PKCS1v15, Hash>::Verifier verifier(m_PublicKey);
return verifier.VerifyMessage(buf, len, signature, keyLen); // signature length
}
size_t GetPublicKeyLen() const { return keyLen; }
size_t GetSignatureLen() const { return keyLen; }
size_t GetPrivateKeyLen() const { return GetSignatureLen()*2; };
private:
CryptoPP::RSA::PublicKey m_PublicKey;
};
template<typename Hash>
class RSASigner: public Signer {
public:
RSASigner(const uint8_t * signingPrivateKey, size_t keyLen)
{
m_PrivateKey.Initialize(CryptoPP::Integer(signingPrivateKey, keyLen/2),
rsae,
CryptoPP::Integer(signingPrivateKey + keyLen/2, keyLen/2));
}
void Sign(CryptoPP::RandomNumberGenerator& rnd, const uint8_t * buf, int len, uint8_t * signature) const
{
typename CryptoPP::RSASS<CryptoPP::PKCS1v15, Hash>::Signer signer(m_PrivateKey);
signer.SignMessage(rnd, buf, len, signature);
}
private:
CryptoPP::RSA::PrivateKey m_PrivateKey;
};
inline void CreateRSARandomKeys(CryptoPP::RandomNumberGenerator& rnd,
size_t publicKeyLen, uint8_t * signingPrivateKey, uint8_t * signingPublicKey)
{
CryptoPP::RSA::PrivateKey privateKey;
privateKey.Initialize(rnd, publicKeyLen*8, rsae);
privateKey.GetModulus().Encode(signingPrivateKey, publicKeyLen);
privateKey.GetPrivateExponent().Encode(signingPrivateKey + publicKeyLen, publicKeyLen);
privateKey.GetModulus().Encode(signingPublicKey, publicKeyLen);
}
// RSA_SHA256_2048
const size_t RSASHA2562048_KEY_LENGTH = 256;
class RSASHA2562048Verifier: public RSAVerifier<CryptoPP::SHA256, RSASHA2562048_KEY_LENGTH>
const size_t RSASHA2562048_KEY_LENGTH = 256;
class RSASHA2562048Verifier: public RSAVerifier<CryptoPP::SHA256, RSASHA2562048_KEY_LENGTH> {
public:
RSASHA2562048Verifier(const uint8_t * signingKey): RSAVerifier(signingKey)
{
public:
}
};
RSASHA2562048Verifier (const uint8_t * signingKey): RSAVerifier (signingKey)
{
}
};
class RSASHA2562048Signer: public RSASigner<CryptoPP::SHA256> {
public:
class RSASHA2562048Signer: public RSASigner<CryptoPP::SHA256>
RSASHA2562048Signer(const uint8_t * signingPrivateKey):
RSASigner(signingPrivateKey, RSASHA2562048_KEY_LENGTH*2)
{
public:
}
};
RSASHA2562048Signer (const uint8_t * signingPrivateKey):
RSASigner (signingPrivateKey, RSASHA2562048_KEY_LENGTH*2)
{
}
};
// RSA_SHA384_3072
const size_t RSASHA3843072_KEY_LENGTH = 384;
class RSASHA3843072Verifier: public RSAVerifier<CryptoPP::SHA384, RSASHA3843072_KEY_LENGTH> {
public:
// RSA_SHA384_3072
const size_t RSASHA3843072_KEY_LENGTH = 384;
class RSASHA3843072Verifier: public RSAVerifier<CryptoPP::SHA384, RSASHA3843072_KEY_LENGTH>
RSASHA3843072Verifier(const uint8_t * signingKey): RSAVerifier(signingKey)
{
public:
}
};
RSASHA3843072Verifier (const uint8_t * signingKey): RSAVerifier (signingKey)
{
}
};
class RSASHA3843072Signer: public RSASigner<CryptoPP::SHA384> {
public:
class RSASHA3843072Signer: public RSASigner<CryptoPP::SHA384>
RSASHA3843072Signer(const uint8_t * signingPrivateKey):
RSASigner(signingPrivateKey, RSASHA3843072_KEY_LENGTH*2)
{
public:
}
};
RSASHA3843072Signer (const uint8_t * signingPrivateKey):
RSASigner (signingPrivateKey, RSASHA3843072_KEY_LENGTH*2)
{
}
};
// RSA_SHA512_4096
const size_t RSASHA5124096_KEY_LENGTH = 512;
class RSASHA5124096Verifier: public RSAVerifier<CryptoPP::SHA512, RSASHA5124096_KEY_LENGTH> {
public:
// RSA_SHA512_4096
const size_t RSASHA5124096_KEY_LENGTH = 512;
class RSASHA5124096Verifier: public RSAVerifier<CryptoPP::SHA512, RSASHA5124096_KEY_LENGTH>
RSASHA5124096Verifier(const uint8_t * signingKey): RSAVerifier(signingKey)
{
public:
}
};
RSASHA5124096Verifier (const uint8_t * signingKey): RSAVerifier (signingKey)
{
}
};
class RSASHA5124096Signer: public RSASigner<CryptoPP::SHA512> {
public:
class RSASHA5124096Signer: public RSASigner<CryptoPP::SHA512>
RSASHA5124096Signer(const uint8_t * signingPrivateKey):
RSASigner(signingPrivateKey, RSASHA5124096_KEY_LENGTH*2)
{
public:
RSASHA5124096Signer (const uint8_t * signingPrivateKey):
RSASigner (signingPrivateKey, RSASHA5124096_KEY_LENGTH*2)
{
}
};
}
};
// Raw verifiers
class RawVerifier
class RawVerifier {
public:
virtual ~RawVerifier() {};
virtual void Update(const uint8_t * buf, size_t len) = 0;
virtual bool Verify(const uint8_t * signature) = 0;
};
template<typename Hash, size_t keyLen>
class RSARawVerifier: public RawVerifier {
public:
RSARawVerifier(const uint8_t * signingKey):
n(signingKey, keyLen)
{
public:
virtual ~RawVerifier () {};
virtual void Update (const uint8_t * buf, size_t len) = 0;
virtual bool Verify (const uint8_t * signature) = 0;
};
}
template<typename Hash, size_t keyLen>
class RSARawVerifier: public RawVerifier
void Update(const uint8_t * buf, size_t len)
{
public:
RSARawVerifier (const uint8_t * signingKey):
n (signingKey, keyLen)
{
}
void Update (const uint8_t * buf, size_t len)
{
m_Hash.Update (buf, len);
}
bool Verify (const uint8_t * signature)
{
// RSA encryption first
CryptoPP::Integer enSig (a_exp_b_mod_c (CryptoPP::Integer (signature, keyLen),
CryptoPP::Integer (i2p::crypto::rsae), n)); // s^e mod n
uint8_t enSigBuf[keyLen];
enSig.Encode (enSigBuf, keyLen);
uint8_t digest[Hash::DIGESTSIZE];
m_Hash.Final (digest);
if ((int)keyLen < Hash::DIGESTSIZE) return false; // can't verify digest longer than key
// we assume digest is right aligned, at least for PKCS#1 v1.5 padding
return !memcmp (enSigBuf + (keyLen - Hash::DIGESTSIZE), digest, Hash::DIGESTSIZE);
}
private:
CryptoPP::Integer n; // RSA modulus
Hash m_Hash;
};
class RSASHA5124096RawVerifier: public RSARawVerifier<CryptoPP::SHA512, RSASHA5124096_KEY_LENGTH>
{
public:
RSASHA5124096RawVerifier (const uint8_t * signingKey): RSARawVerifier (signingKey)
{
}
};
// EdDSA
const size_t EDDSA25519_PUBLIC_KEY_LENGTH = 32;
const size_t EDDSA25519_SIGNATURE_LENGTH = 64;
const size_t EDDSA25519_PRIVATE_KEY_LENGTH = 32;
class EDDSA25519Verifier: public Verifier
{
public:
EDDSA25519Verifier (const uint8_t * signingKey);
bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const;
size_t GetPublicKeyLen () const { return EDDSA25519_PUBLIC_KEY_LENGTH; };
size_t GetSignatureLen () const { return EDDSA25519_SIGNATURE_LENGTH; };
private:
m_Hash.Update(buf, len);
}
CryptoPP::ECP::Point m_PublicKey;
};
class EDDSA25519Signer: public Signer
bool Verify(const uint8_t * signature)
{
public:
// RSA encryption first
CryptoPP::Integer enSig(a_exp_b_mod_c(CryptoPP::Integer(signature, keyLen),
CryptoPP::Integer(i2p::crypto::rsae), n)); // s^e mod n
uint8_t enSigBuf[keyLen];
enSig.Encode(enSigBuf, keyLen);
EDDSA25519Signer (const uint8_t * signingPrivateKey) {};
uint8_t digest[Hash::DIGESTSIZE];
m_Hash.Final(digest);
if((int)keyLen < Hash::DIGESTSIZE) return false; // can't verify digest longer than key
// we assume digest is right aligned, at least for PKCS#1 v1.5 padding
return !memcmp(enSigBuf +(keyLen - Hash::DIGESTSIZE), digest, Hash::DIGESTSIZE);
}
void Sign (CryptoPP::RandomNumberGenerator& rnd, const uint8_t * buf, int len, uint8_t * signature) const;
};
}
}
private:
CryptoPP::Integer n; // RSA modulus
Hash m_Hash;
};
class RSASHA5124096RawVerifier: public RSARawVerifier<CryptoPP::SHA512, RSASHA5124096_KEY_LENGTH> {
public:
RSASHA5124096RawVerifier(const uint8_t * signingKey): RSARawVerifier(signingKey)
{
}
};
} // crypto
} // i2p
#endif

View File

@ -0,0 +1,29 @@
#ifndef SIGNATUREBASE_H__
#define SIGNATUREBASE_H__
#include <cryptopp/osrng.h>
namespace i2p {
namespace crypto {
class Verifier {
public:
virtual ~Verifier() {};
virtual bool Verify(const uint8_t * buf, size_t len, const uint8_t * signature) const = 0;
virtual size_t GetPublicKeyLen() const = 0;
virtual size_t GetSignatureLen() const = 0;
virtual size_t GetPrivateKeyLen() const { return GetSignatureLen()/2; };
};
class Signer {
public:
virtual ~Signer() {};
virtual void Sign(CryptoPP::RandomNumberGenerator& rnd, const uint8_t * buf, int len, uint8_t * signature) const = 0;
};
}
}
#endif // SIGNATUREBASE_H__

View File

@ -0,0 +1 @@

View File

@ -0,0 +1,4 @@
#define CRYPTO_SECRETKEYBYTES 64
#define CRYPTO_PUBLICKEYBYTES 32
#define CRYPTO_BYTES 64
#define CRYPTO_DETERMINISTIC 1

1344
core/crypto/ed25519/base.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,65 @@
b = 256
q = 2**255 - 19
l = 2**252 + 27742317777372353535851937790883648493
def expmod(b,e,m):
if e == 0: return 1
t = expmod(b,e/2,m)**2 % m
if e & 1: t = (t*b) % m
return t
def inv(x):
return expmod(x,q-2,q)
d = -121665 * inv(121666)
I = expmod(2,(q-1)/4,q)
def xrecover(y):
xx = (y*y-1) * inv(d*y*y+1)
x = expmod(xx,(q+3)/8,q)
if (x*x - xx) % q != 0: x = (x*I) % q
if x % 2 != 0: x = q-x
return x
By = 4 * inv(5)
Bx = xrecover(By)
B = [Bx % q,By % q]
def edwards(P,Q):
x1 = P[0]
y1 = P[1]
x2 = Q[0]
y2 = Q[1]
x3 = (x1*y2+x2*y1) * inv(1+d*x1*x2*y1*y2)
y3 = (y1*y2+x1*x2) * inv(1-d*x1*x2*y1*y2)
return [x3 % q,y3 % q]
def radix255(x):
x = x % q
if x + x > q: x -= q
x = [x,0,0,0,0,0,0,0,0,0]
bits = [26,25,26,25,26,25,26,25,26,25]
for i in range(9):
carry = (x[i] + 2**(bits[i]-1)) / 2**bits[i]
x[i] -= carry * 2**bits[i]
x[i + 1] += carry
result = ""
for i in range(9):
result = result+str(x[i])+","
result = result+str(x[9])
return result
Bi = B
for i in range(32):
print "{"
Bij = Bi
for j in range(8):
print " {"
print " {",radix255(Bij[1]+Bij[0]),"},"
print " {",radix255(Bij[1]-Bij[0]),"},"
print " {",radix255(2*d*Bij[0]*Bij[1]),"},"
Bij = edwards(Bij,Bi)
print " },"
print "},"
for k in range(8):
Bi = edwards(Bi,Bi)

View File

@ -0,0 +1,40 @@
{
{ 25967493,-14356035,29566456,3660896,-12694345,4014787,27544626,-11754271,-6079156,2047605 },
{ -12545711,934262,-2722910,3049990,-727428,9406986,12720692,5043384,19500929,-15469378 },
{ -8738181,4489570,9688441,-14785194,10184609,-12363380,29287919,11864899,-24514362,-4438546 },
},
{
{ 15636291,-9688557,24204773,-7912398,616977,-16685262,27787600,-14772189,28944400,-1550024 },
{ 16568933,4717097,-11556148,-1102322,15682896,-11807043,16354577,-11775962,7689662,11199574 },
{ 30464156,-5976125,-11779434,-15670865,23220365,15915852,7512774,10017326,-17749093,-9920357 },
},
{
{ 10861363,11473154,27284546,1981175,-30064349,12577861,32867885,14515107,-15438304,10819380 },
{ 4708026,6336745,20377586,9066809,-11272109,6594696,-25653668,12483688,-12668491,5581306 },
{ 19563160,16186464,-29386857,4097519,10237984,-4348115,28542350,13850243,-23678021,-15815942 },
},
{
{ 5153746,9909285,1723747,-2777874,30523605,5516873,19480852,5230134,-23952439,-15175766 },
{ -30269007,-3463509,7665486,10083793,28475525,1649722,20654025,16520125,30598449,7715701 },
{ 28881845,14381568,9657904,3680757,-20181635,7843316,-31400660,1370708,29794553,-1409300 },
},
{
{ -22518993,-6692182,14201702,-8745502,-23510406,8844726,18474211,-1361450,-13062696,13821877 },
{ -6455177,-7839871,3374702,-4740862,-27098617,-10571707,31655028,-7212327,18853322,-14220951 },
{ 4566830,-12963868,-28974889,-12240689,-7602672,-2830569,-8514358,-10431137,2207753,-3209784 },
},
{
{ -25154831,-4185821,29681144,7868801,-6854661,-9423865,-12437364,-663000,-31111463,-16132436 },
{ 25576264,-2703214,7349804,-11814844,16472782,9300885,3844789,15725684,171356,6466918 },
{ 23103977,13316479,9739013,-16149481,817875,-15038942,8965339,-14088058,-30714912,16193877 },
},
{
{ -33521811,3180713,-2394130,14003687,-16903474,-16270840,17238398,4729455,-18074513,9256800 },
{ -25182317,-4174131,32336398,5036987,-21236817,11360617,22616405,9761698,-19827198,630305 },
{ -13720693,2639453,-24237460,-7406481,9494427,-5774029,-6554551,-15960994,-2449256,-14291300 },
},
{
{ -3151181,-5046075,9282714,6866145,-31907062,-863023,-18940575,15033784,25105118,-7894876 },
{ -24326370,15950226,-31801215,-14592823,-11662737,-5090925,1573892,-2625887,2198790,-15804619 },
{ -3099351,10324967,-2241613,7453183,-5446979,-2735503,-13812022,-16236442,-32461234,-12290683 },
},

View File

@ -0,0 +1,60 @@
b = 256
q = 2**255 - 19
l = 2**252 + 27742317777372353535851937790883648493
def expmod(b,e,m):
if e == 0: return 1
t = expmod(b,e/2,m)**2 % m
if e & 1: t = (t*b) % m
return t
def inv(x):
return expmod(x,q-2,q)
d = -121665 * inv(121666)
I = expmod(2,(q-1)/4,q)
def xrecover(y):
xx = (y*y-1) * inv(d*y*y+1)
x = expmod(xx,(q+3)/8,q)
if (x*x - xx) % q != 0: x = (x*I) % q
if x % 2 != 0: x = q-x
return x
By = 4 * inv(5)
Bx = xrecover(By)
B = [Bx % q,By % q]
def edwards(P,Q):
x1 = P[0]
y1 = P[1]
x2 = Q[0]
y2 = Q[1]
x3 = (x1*y2+x2*y1) * inv(1+d*x1*x2*y1*y2)
y3 = (y1*y2+x1*x2) * inv(1-d*x1*x2*y1*y2)
return [x3 % q,y3 % q]
def radix255(x):
x = x % q
if x + x > q: x -= q
x = [x,0,0,0,0,0,0,0,0,0]
bits = [26,25,26,25,26,25,26,25,26,25]
for i in range(9):
carry = (x[i] + 2**(bits[i]-1)) / 2**bits[i]
x[i] -= carry * 2**bits[i]
x[i + 1] += carry
result = ""
for i in range(9):
result = result+str(x[i])+","
result = result+str(x[9])
return result
Bi = B
for i in range(8):
print " {"
print " {",radix255(Bi[1]+Bi[0]),"},"
print " {",radix255(Bi[1]-Bi[0]),"},"
print " {",radix255(2*d*Bi[0]*Bi[1]),"},"
print " },"
Bi = edwards(B,edwards(B,Bi))

View File

@ -0,0 +1,37 @@
#ifndef CRYPTO_HASH_SHA512_H__
#define CRYPTO_HASH_SHA512_H__
#include <cryptopp/sha.h>
inline void crypto_hash_sha512(unsigned char* output, const unsigned char* input,
size_t len)
{
CryptoPP::SHA512 hash;
hash.CalculateDigest(output, input, len);
}
inline void crypto_hash_sha512_2(unsigned char* out,
const unsigned char* in1, size_t len1,
const unsigned char* in2, size_t len2
)
{
CryptoPP::SHA512 hash;
hash.Update(in1, len1);
hash.Update(in2, len2);
hash.Final(out);
}
inline void crypto_hash_sha512_3(unsigned char* out,
const unsigned char* in1, size_t len1,
const unsigned char* in2, size_t len2,
const unsigned char* in3, size_t len3
)
{
CryptoPP::SHA512 hash;
hash.Update(in1, len1);
hash.Update(in2, len2);
hash.Update(in3, len3);
hash.Final(out);
}
#endif // CRYPTO_HASH_SHA512_H__

View File

@ -0,0 +1,3 @@
#include <inttypes.h>
#define crypto_int32 int32_t

View File

@ -0,0 +1,3 @@
#include <inttypes.h>
#define crypto_int64 int64_t

View File

@ -0,0 +1,5 @@
#define crypto_sign ed25519_ref10_sign
#define crypto_sign_pubkey ed25519_ref10_pubkey
#define crypto_sign_open ed25519_ref10_open
#include "ed25519_ref10.h"

View File

@ -0,0 +1,3 @@
#include <inttypes.h>
#define crypto_uint32 uint32_t

View File

@ -0,0 +1,3 @@
#include <inttypes.h>
#define crypto_uint64 uint64_t

View File

@ -0,0 +1,3 @@
#include <cstring>
#define crypto_verify_32(a,b) (!!std::memcmp((a), (b), 32))

1
core/crypto/ed25519/d.h Normal file
View File

@ -0,0 +1 @@
-10913610,13857413,-15372611,6949391,114729,-8787816,-6275908,-3247719,-18696448,-12055116

28
core/crypto/ed25519/d.py Normal file
View File

@ -0,0 +1,28 @@
q = 2**255 - 19
def expmod(b,e,m):
if e == 0: return 1
t = expmod(b,e/2,m)**2 % m
if e & 1: t = (t*b) % m
return t
def inv(x):
return expmod(x,q-2,q)
def radix255(x):
x = x % q
if x + x > q: x -= q
x = [x,0,0,0,0,0,0,0,0,0]
bits = [26,25,26,25,26,25,26,25,26,25]
for i in range(9):
carry = (x[i] + 2**(bits[i]-1)) / 2**bits[i]
x[i] -= carry * 2**bits[i]
x[i + 1] += carry
result = ""
for i in range(9):
result = result+str(x[i])+","
result = result+str(x[9])
return result
d = -121665 * inv(121666)
print radix255(d)

1
core/crypto/ed25519/d2.h Normal file
View File

@ -0,0 +1 @@
-21827239,-5839606,-30745221,13898782,229458,15978800,-12551817,-6495438,29715968,9444199

28
core/crypto/ed25519/d2.py Normal file
View File

@ -0,0 +1,28 @@
q = 2**255 - 19
def expmod(b,e,m):
if e == 0: return 1
t = expmod(b,e/2,m)**2 % m
if e & 1: t = (t*b) % m
return t
def inv(x):
return expmod(x,q-2,q)
def radix255(x):
x = x % q
if x + x > q: x -= q
x = [x,0,0,0,0,0,0,0,0,0]
bits = [26,25,26,25,26,25,26,25,26,25]
for i in range(9):
carry = (x[i] + 2**(bits[i]-1)) / 2**bits[i]
x[i] -= carry * 2**bits[i]
x[i + 1] += carry
result = ""
for i in range(9):
result = result+str(x[i])+","
result = result+str(x[9])
return result
d = -121665 * inv(121666)
print radix255(d*2)

View File

@ -0,0 +1,22 @@
#ifndef ED25519_REF10_H__
#define ED25519_REF10_H__
/**
* Generate a public key from a given private key.
*/
int ed25519_ref10_pubkey(unsigned char* pk, const unsigned char* sk);
int ed25519_ref10_open(
const unsigned char* sig,
const unsigned char* m, size_t mlen,
const unsigned char*pk
);
int ed25519_ref10_sign(
unsigned char* sig,
const unsigned char* m, size_t mlen,
const unsigned char* sk, const unsigned char* pk
);
#endif // ED25519_REF10_H__

56
core/crypto/ed25519/fe.h Normal file
View File

@ -0,0 +1,56 @@
#ifndef FE_H
#define FE_H
#include "crypto_int32.h"
typedef crypto_int32 fe[10];
/*
fe means field element.
Here the field is \Z/(2^255-19).
An element t, entries t[0]...t[9], represents the integer
t[0]+2^26 t[1]+2^51 t[2]+2^77 t[3]+2^102 t[4]+...+2^230 t[9].
Bounds on each t[i] vary depending on context.
*/
#define fe_frombytes crypto_sign_ed25519_ref10_fe_frombytes
#define fe_tobytes crypto_sign_ed25519_ref10_fe_tobytes
#define fe_copy crypto_sign_ed25519_ref10_fe_copy
#define fe_isnonzero crypto_sign_ed25519_ref10_fe_isnonzero
#define fe_isnegative crypto_sign_ed25519_ref10_fe_isnegative
#define fe_0 crypto_sign_ed25519_ref10_fe_0
#define fe_1 crypto_sign_ed25519_ref10_fe_1
#define fe_cswap crypto_sign_ed25519_ref10_fe_cswap
#define fe_cmov crypto_sign_ed25519_ref10_fe_cmov
#define fe_add crypto_sign_ed25519_ref10_fe_add
#define fe_sub crypto_sign_ed25519_ref10_fe_sub
#define fe_neg crypto_sign_ed25519_ref10_fe_neg
#define fe_mul crypto_sign_ed25519_ref10_fe_mul
#define fe_sq crypto_sign_ed25519_ref10_fe_sq
#define fe_sq2 crypto_sign_ed25519_ref10_fe_sq2
#define fe_mul121666 crypto_sign_ed25519_ref10_fe_mul121666
#define fe_invert crypto_sign_ed25519_ref10_fe_invert
#define fe_pow22523 crypto_sign_ed25519_ref10_fe_pow22523
extern void fe_frombytes(fe,const unsigned char *);
extern void fe_tobytes(unsigned char *,const fe);
extern void fe_copy(fe,const fe);
extern int fe_isnonzero(const fe);
extern int fe_isnegative(const fe);
extern void fe_0(fe);
extern void fe_1(fe);
extern void fe_cswap(fe,fe,unsigned int);
extern void fe_cmov(fe,const fe,unsigned int);
extern void fe_add(fe,const fe,const fe);
extern void fe_sub(fe,const fe,const fe);
extern void fe_neg(fe,const fe);
extern void fe_mul(fe,const fe,const fe);
extern void fe_sq(fe,const fe);
extern void fe_sq2(fe,const fe);
extern void fe_mul121666(fe,const fe);
extern void fe_invert(fe,const fe);
extern void fe_pow22523(fe,const fe);
#endif

View File

@ -0,0 +1,19 @@
#include "fe.h"
/*
h = 0
*/
void fe_0(fe h)
{
h[0] = 0;
h[1] = 0;
h[2] = 0;
h[3] = 0;
h[4] = 0;
h[5] = 0;
h[6] = 0;
h[7] = 0;
h[8] = 0;
h[9] = 0;
}

View File

@ -0,0 +1,19 @@
#include "fe.h"
/*
h = 1
*/
void fe_1(fe h)
{
h[0] = 1;
h[1] = 0;
h[2] = 0;
h[3] = 0;
h[4] = 0;
h[5] = 0;
h[6] = 0;
h[7] = 0;
h[8] = 0;
h[9] = 0;
}

View File

@ -0,0 +1,57 @@
#include "fe.h"
/*
h = f + g
Can overlap h with f or g.
Preconditions:
|f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
|g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
Postconditions:
|h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
*/
void fe_add(fe h,const fe f,const fe g)
{
crypto_int32 f0 = f[0];
crypto_int32 f1 = f[1];
crypto_int32 f2 = f[2];
crypto_int32 f3 = f[3];
crypto_int32 f4 = f[4];
crypto_int32 f5 = f[5];
crypto_int32 f6 = f[6];
crypto_int32 f7 = f[7];
crypto_int32 f8 = f[8];
crypto_int32 f9 = f[9];
crypto_int32 g0 = g[0];
crypto_int32 g1 = g[1];
crypto_int32 g2 = g[2];
crypto_int32 g3 = g[3];
crypto_int32 g4 = g[4];
crypto_int32 g5 = g[5];
crypto_int32 g6 = g[6];
crypto_int32 g7 = g[7];
crypto_int32 g8 = g[8];
crypto_int32 g9 = g[9];
crypto_int32 h0 = f0 + g0;
crypto_int32 h1 = f1 + g1;
crypto_int32 h2 = f2 + g2;
crypto_int32 h3 = f3 + g3;
crypto_int32 h4 = f4 + g4;
crypto_int32 h5 = f5 + g5;
crypto_int32 h6 = f6 + g6;
crypto_int32 h7 = f7 + g7;
crypto_int32 h8 = f8 + g8;
crypto_int32 h9 = f9 + g9;
h[0] = h0;
h[1] = h1;
h[2] = h2;
h[3] = h3;
h[4] = h4;
h[5] = h5;
h[6] = h6;
h[7] = h7;
h[8] = h8;
h[9] = h9;
}

View File

@ -0,0 +1,63 @@
#include "fe.h"
/*
Replace (f,g) with (g,g) if b == 1;
replace (f,g) with (f,g) if b == 0.
Preconditions: b in {0,1}.
*/
void fe_cmov(fe f,const fe g,unsigned int b)
{
crypto_int32 f0 = f[0];
crypto_int32 f1 = f[1];
crypto_int32 f2 = f[2];
crypto_int32 f3 = f[3];
crypto_int32 f4 = f[4];
crypto_int32 f5 = f[5];
crypto_int32 f6 = f[6];
crypto_int32 f7 = f[7];
crypto_int32 f8 = f[8];
crypto_int32 f9 = f[9];
crypto_int32 g0 = g[0];
crypto_int32 g1 = g[1];
crypto_int32 g2 = g[2];
crypto_int32 g3 = g[3];
crypto_int32 g4 = g[4];
crypto_int32 g5 = g[5];
crypto_int32 g6 = g[6];
crypto_int32 g7 = g[7];
crypto_int32 g8 = g[8];
crypto_int32 g9 = g[9];
crypto_int32 x0 = f0 ^ g0;
crypto_int32 x1 = f1 ^ g1;
crypto_int32 x2 = f2 ^ g2;
crypto_int32 x3 = f3 ^ g3;
crypto_int32 x4 = f4 ^ g4;
crypto_int32 x5 = f5 ^ g5;
crypto_int32 x6 = f6 ^ g6;
crypto_int32 x7 = f7 ^ g7;
crypto_int32 x8 = f8 ^ g8;
crypto_int32 x9 = f9 ^ g9;
b = -b;
x0 &= b;
x1 &= b;
x2 &= b;
x3 &= b;
x4 &= b;
x5 &= b;
x6 &= b;
x7 &= b;
x8 &= b;
x9 &= b;
f[0] = f0 ^ x0;
f[1] = f1 ^ x1;
f[2] = f2 ^ x2;
f[3] = f3 ^ x3;
f[4] = f4 ^ x4;
f[5] = f5 ^ x5;
f[6] = f6 ^ x6;
f[7] = f7 ^ x7;
f[8] = f8 ^ x8;
f[9] = f9 ^ x9;
}

View File

@ -0,0 +1,29 @@
#include "fe.h"
/*
h = f
*/
void fe_copy(fe h,const fe f)
{
crypto_int32 f0 = f[0];
crypto_int32 f1 = f[1];
crypto_int32 f2 = f[2];
crypto_int32 f3 = f[3];
crypto_int32 f4 = f[4];
crypto_int32 f5 = f[5];
crypto_int32 f6 = f[6];
crypto_int32 f7 = f[7];
crypto_int32 f8 = f[8];
crypto_int32 f9 = f[9];
h[0] = f0;
h[1] = f1;
h[2] = f2;
h[3] = f3;
h[4] = f4;
h[5] = f5;
h[6] = f6;
h[7] = f7;
h[8] = f8;
h[9] = f9;
}

View File

@ -0,0 +1,73 @@
#include "fe.h"
#include "crypto_int64.h"
#include "crypto_uint64.h"
static crypto_uint64 load_3(const unsigned char *in)
{
crypto_uint64 result;
result = (crypto_uint64) in[0];
result |= ((crypto_uint64) in[1]) << 8;
result |= ((crypto_uint64) in[2]) << 16;
return result;
}
static crypto_uint64 load_4(const unsigned char *in)
{
crypto_uint64 result;
result = (crypto_uint64) in[0];
result |= ((crypto_uint64) in[1]) << 8;
result |= ((crypto_uint64) in[2]) << 16;
result |= ((crypto_uint64) in[3]) << 24;
return result;
}
/*
Ignores top bit of h.
*/
void fe_frombytes(fe h,const unsigned char *s)
{
crypto_int64 h0 = load_4(s);
crypto_int64 h1 = load_3(s + 4) << 6;
crypto_int64 h2 = load_3(s + 7) << 5;
crypto_int64 h3 = load_3(s + 10) << 3;
crypto_int64 h4 = load_3(s + 13) << 2;
crypto_int64 h5 = load_4(s + 16);
crypto_int64 h6 = load_3(s + 20) << 7;
crypto_int64 h7 = load_3(s + 23) << 5;
crypto_int64 h8 = load_3(s + 26) << 4;
crypto_int64 h9 = (load_3(s + 29) & 8388607) << 2;
crypto_int64 carry0;
crypto_int64 carry1;
crypto_int64 carry2;
crypto_int64 carry3;
crypto_int64 carry4;
crypto_int64 carry5;
crypto_int64 carry6;
crypto_int64 carry7;
crypto_int64 carry8;
crypto_int64 carry9;
carry9 = (h9 + (crypto_int64) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;
carry1 = (h1 + (crypto_int64) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25;
carry3 = (h3 + (crypto_int64) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25;
carry5 = (h5 + (crypto_int64) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25;
carry7 = (h7 + (crypto_int64) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25;
carry0 = (h0 + (crypto_int64) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
carry2 = (h2 + (crypto_int64) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26;
carry4 = (h4 + (crypto_int64) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
carry6 = (h6 + (crypto_int64) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26;
carry8 = (h8 + (crypto_int64) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26;
h[0] = h0;
h[1] = h1;
h[2] = h2;
h[3] = h3;
h[4] = h4;
h[5] = h5;
h[6] = h6;
h[7] = h7;
h[8] = h8;
h[9] = h9;
}

View File

@ -0,0 +1,14 @@
#include "fe.h"
void fe_invert(fe out,const fe z)
{
fe t0;
fe t1;
fe t2;
fe t3;
int i;
#include "pow225521.h"
return;
}

View File

@ -0,0 +1,16 @@
#include "fe.h"
/*
return 1 if f is in {1,3,5,...,q-2}
return 0 if f is in {0,2,4,...,q-1}
Preconditions:
|f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
*/
int fe_isnegative(const fe f)
{
unsigned char s[32];
fe_tobytes(s,f);
return s[0] & 1;
}

View File

@ -0,0 +1,19 @@
#include "fe.h"
#include "crypto_verify_32.h"
/*
return 1 if f == 0
return 0 if f != 0
Preconditions:
|f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
*/
static const unsigned char zero[32] = {};
int fe_isnonzero(const fe f)
{
unsigned char s[32];
fe_tobytes(s,f);
return crypto_verify_32(s,zero);
}

View File

@ -0,0 +1,253 @@
#include "fe.h"
#include "crypto_int64.h"
/*
h = f * g
Can overlap h with f or g.
Preconditions:
|f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
|g| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
Postconditions:
|h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.
*/
/*
Notes on implementation strategy:
Using schoolbook multiplication.
Karatsuba would save a little in some cost models.
Most multiplications by 2 and 19 are 32-bit precomputations;
cheaper than 64-bit postcomputations.
There is one remaining multiplication by 19 in the carry chain;
one *19 precomputation can be merged into this,
but the resulting data flow is considerably less clean.
There are 12 carries below.
10 of them are 2-way parallelizable and vectorizable.
Can get away with 11 carries, but then data flow is much deeper.
With tighter constraints on inputs can squeeze carries into int32.
*/
void fe_mul(fe h,const fe f,const fe g)
{
crypto_int32 f0 = f[0];
crypto_int32 f1 = f[1];
crypto_int32 f2 = f[2];
crypto_int32 f3 = f[3];
crypto_int32 f4 = f[4];
crypto_int32 f5 = f[5];
crypto_int32 f6 = f[6];
crypto_int32 f7 = f[7];
crypto_int32 f8 = f[8];
crypto_int32 f9 = f[9];
crypto_int32 g0 = g[0];
crypto_int32 g1 = g[1];
crypto_int32 g2 = g[2];
crypto_int32 g3 = g[3];
crypto_int32 g4 = g[4];
crypto_int32 g5 = g[5];
crypto_int32 g6 = g[6];
crypto_int32 g7 = g[7];
crypto_int32 g8 = g[8];
crypto_int32 g9 = g[9];
crypto_int32 g1_19 = 19 * g1; /* 1.959375*2^29 */
crypto_int32 g2_19 = 19 * g2; /* 1.959375*2^30; still ok */
crypto_int32 g3_19 = 19 * g3;
crypto_int32 g4_19 = 19 * g4;
crypto_int32 g5_19 = 19 * g5;
crypto_int32 g6_19 = 19 * g6;
crypto_int32 g7_19 = 19 * g7;
crypto_int32 g8_19 = 19 * g8;
crypto_int32 g9_19 = 19 * g9;
crypto_int32 f1_2 = 2 * f1;
crypto_int32 f3_2 = 2 * f3;
crypto_int32 f5_2 = 2 * f5;
crypto_int32 f7_2 = 2 * f7;
crypto_int32 f9_2 = 2 * f9;
crypto_int64 f0g0 = f0 * (crypto_int64) g0;
crypto_int64 f0g1 = f0 * (crypto_int64) g1;
crypto_int64 f0g2 = f0 * (crypto_int64) g2;
crypto_int64 f0g3 = f0 * (crypto_int64) g3;
crypto_int64 f0g4 = f0 * (crypto_int64) g4;
crypto_int64 f0g5 = f0 * (crypto_int64) g5;
crypto_int64 f0g6 = f0 * (crypto_int64) g6;
crypto_int64 f0g7 = f0 * (crypto_int64) g7;
crypto_int64 f0g8 = f0 * (crypto_int64) g8;
crypto_int64 f0g9 = f0 * (crypto_int64) g9;
crypto_int64 f1g0 = f1 * (crypto_int64) g0;
crypto_int64 f1g1_2 = f1_2 * (crypto_int64) g1;
crypto_int64 f1g2 = f1 * (crypto_int64) g2;
crypto_int64 f1g3_2 = f1_2 * (crypto_int64) g3;
crypto_int64 f1g4 = f1 * (crypto_int64) g4;
crypto_int64 f1g5_2 = f1_2 * (crypto_int64) g5;
crypto_int64 f1g6 = f1 * (crypto_int64) g6;
crypto_int64 f1g7_2 = f1_2 * (crypto_int64) g7;
crypto_int64 f1g8 = f1 * (crypto_int64) g8;
crypto_int64 f1g9_38 = f1_2 * (crypto_int64) g9_19;
crypto_int64 f2g0 = f2 * (crypto_int64) g0;
crypto_int64 f2g1 = f2 * (crypto_int64) g1;
crypto_int64 f2g2 = f2 * (crypto_int64) g2;
crypto_int64 f2g3 = f2 * (crypto_int64) g3;
crypto_int64 f2g4 = f2 * (crypto_int64) g4;
crypto_int64 f2g5 = f2 * (crypto_int64) g5;
crypto_int64 f2g6 = f2 * (crypto_int64) g6;
crypto_int64 f2g7 = f2 * (crypto_int64) g7;
crypto_int64 f2g8_19 = f2 * (crypto_int64) g8_19;
crypto_int64 f2g9_19 = f2 * (crypto_int64) g9_19;
crypto_int64 f3g0 = f3 * (crypto_int64) g0;
crypto_int64 f3g1_2 = f3_2 * (crypto_int64) g1;
crypto_int64 f3g2 = f3 * (crypto_int64) g2;
crypto_int64 f3g3_2 = f3_2 * (crypto_int64) g3;
crypto_int64 f3g4 = f3 * (crypto_int64) g4;
crypto_int64 f3g5_2 = f3_2 * (crypto_int64) g5;
crypto_int64 f3g6 = f3 * (crypto_int64) g6;
crypto_int64 f3g7_38 = f3_2 * (crypto_int64) g7_19;
crypto_int64 f3g8_19 = f3 * (crypto_int64) g8_19;
crypto_int64 f3g9_38 = f3_2 * (crypto_int64) g9_19;
crypto_int64 f4g0 = f4 * (crypto_int64) g0;
crypto_int64 f4g1 = f4 * (crypto_int64) g1;
crypto_int64 f4g2 = f4 * (crypto_int64) g2;
crypto_int64 f4g3 = f4 * (crypto_int64) g3;
crypto_int64 f4g4 = f4 * (crypto_int64) g4;
crypto_int64 f4g5 = f4 * (crypto_int64) g5;
crypto_int64 f4g6_19 = f4 * (crypto_int64) g6_19;
crypto_int64 f4g7_19 = f4 * (crypto_int64) g7_19;
crypto_int64 f4g8_19 = f4 * (crypto_int64) g8_19;
crypto_int64 f4g9_19 = f4 * (crypto_int64) g9_19;
crypto_int64 f5g0 = f5 * (crypto_int64) g0;
crypto_int64 f5g1_2 = f5_2 * (crypto_int64) g1;
crypto_int64 f5g2 = f5 * (crypto_int64) g2;
crypto_int64 f5g3_2 = f5_2 * (crypto_int64) g3;
crypto_int64 f5g4 = f5 * (crypto_int64) g4;
crypto_int64 f5g5_38 = f5_2 * (crypto_int64) g5_19;
crypto_int64 f5g6_19 = f5 * (crypto_int64) g6_19;
crypto_int64 f5g7_38 = f5_2 * (crypto_int64) g7_19;
crypto_int64 f5g8_19 = f5 * (crypto_int64) g8_19;
crypto_int64 f5g9_38 = f5_2 * (crypto_int64) g9_19;
crypto_int64 f6g0 = f6 * (crypto_int64) g0;
crypto_int64 f6g1 = f6 * (crypto_int64) g1;
crypto_int64 f6g2 = f6 * (crypto_int64) g2;
crypto_int64 f6g3 = f6 * (crypto_int64) g3;
crypto_int64 f6g4_19 = f6 * (crypto_int64) g4_19;
crypto_int64 f6g5_19 = f6 * (crypto_int64) g5_19;
crypto_int64 f6g6_19 = f6 * (crypto_int64) g6_19;
crypto_int64 f6g7_19 = f6 * (crypto_int64) g7_19;
crypto_int64 f6g8_19 = f6 * (crypto_int64) g8_19;
crypto_int64 f6g9_19 = f6 * (crypto_int64) g9_19;
crypto_int64 f7g0 = f7 * (crypto_int64) g0;
crypto_int64 f7g1_2 = f7_2 * (crypto_int64) g1;
crypto_int64 f7g2 = f7 * (crypto_int64) g2;
crypto_int64 f7g3_38 = f7_2 * (crypto_int64) g3_19;
crypto_int64 f7g4_19 = f7 * (crypto_int64) g4_19;
crypto_int64 f7g5_38 = f7_2 * (crypto_int64) g5_19;
crypto_int64 f7g6_19 = f7 * (crypto_int64) g6_19;
crypto_int64 f7g7_38 = f7_2 * (crypto_int64) g7_19;
crypto_int64 f7g8_19 = f7 * (crypto_int64) g8_19;
crypto_int64 f7g9_38 = f7_2 * (crypto_int64) g9_19;
crypto_int64 f8g0 = f8 * (crypto_int64) g0;
crypto_int64 f8g1 = f8 * (crypto_int64) g1;
crypto_int64 f8g2_19 = f8 * (crypto_int64) g2_19;
crypto_int64 f8g3_19 = f8 * (crypto_int64) g3_19;
crypto_int64 f8g4_19 = f8 * (crypto_int64) g4_19;
crypto_int64 f8g5_19 = f8 * (crypto_int64) g5_19;
crypto_int64 f8g6_19 = f8 * (crypto_int64) g6_19;
crypto_int64 f8g7_19 = f8 * (crypto_int64) g7_19;
crypto_int64 f8g8_19 = f8 * (crypto_int64) g8_19;
crypto_int64 f8g9_19 = f8 * (crypto_int64) g9_19;
crypto_int64 f9g0 = f9 * (crypto_int64) g0;
crypto_int64 f9g1_38 = f9_2 * (crypto_int64) g1_19;
crypto_int64 f9g2_19 = f9 * (crypto_int64) g2_19;
crypto_int64 f9g3_38 = f9_2 * (crypto_int64) g3_19;
crypto_int64 f9g4_19 = f9 * (crypto_int64) g4_19;
crypto_int64 f9g5_38 = f9_2 * (crypto_int64) g5_19;
crypto_int64 f9g6_19 = f9 * (crypto_int64) g6_19;
crypto_int64 f9g7_38 = f9_2 * (crypto_int64) g7_19;
crypto_int64 f9g8_19 = f9 * (crypto_int64) g8_19;
crypto_int64 f9g9_38 = f9_2 * (crypto_int64) g9_19;
crypto_int64 h0 = f0g0+f1g9_38+f2g8_19+f3g7_38+f4g6_19+f5g5_38+f6g4_19+f7g3_38+f8g2_19+f9g1_38;
crypto_int64 h1 = f0g1+f1g0 +f2g9_19+f3g8_19+f4g7_19+f5g6_19+f6g5_19+f7g4_19+f8g3_19+f9g2_19;
crypto_int64 h2 = f0g2+f1g1_2 +f2g0 +f3g9_38+f4g8_19+f5g7_38+f6g6_19+f7g5_38+f8g4_19+f9g3_38;
crypto_int64 h3 = f0g3+f1g2 +f2g1 +f3g0 +f4g9_19+f5g8_19+f6g7_19+f7g6_19+f8g5_19+f9g4_19;
crypto_int64 h4 = f0g4+f1g3_2 +f2g2 +f3g1_2 +f4g0 +f5g9_38+f6g8_19+f7g7_38+f8g6_19+f9g5_38;
crypto_int64 h5 = f0g5+f1g4 +f2g3 +f3g2 +f4g1 +f5g0 +f6g9_19+f7g8_19+f8g7_19+f9g6_19;
crypto_int64 h6 = f0g6+f1g5_2 +f2g4 +f3g3_2 +f4g2 +f5g1_2 +f6g0 +f7g9_38+f8g8_19+f9g7_38;
crypto_int64 h7 = f0g7+f1g6 +f2g5 +f3g4 +f4g3 +f5g2 +f6g1 +f7g0 +f8g9_19+f9g8_19;
crypto_int64 h8 = f0g8+f1g7_2 +f2g6 +f3g5_2 +f4g4 +f5g3_2 +f6g2 +f7g1_2 +f8g0 +f9g9_38;
crypto_int64 h9 = f0g9+f1g8 +f2g7 +f3g6 +f4g5 +f5g4 +f6g3 +f7g2 +f8g1 +f9g0 ;
crypto_int64 carry0;
crypto_int64 carry1;
crypto_int64 carry2;
crypto_int64 carry3;
crypto_int64 carry4;
crypto_int64 carry5;
crypto_int64 carry6;
crypto_int64 carry7;
crypto_int64 carry8;
crypto_int64 carry9;
/*
|h0| <= (1.65*1.65*2^52*(1+19+19+19+19)+1.65*1.65*2^50*(38+38+38+38+38))
i.e. |h0| <= 1.4*2^60; narrower ranges for h2, h4, h6, h8
|h1| <= (1.65*1.65*2^51*(1+1+19+19+19+19+19+19+19+19))
i.e. |h1| <= 1.7*2^59; narrower ranges for h3, h5, h7, h9
*/
carry0 = (h0 + (crypto_int64) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
carry4 = (h4 + (crypto_int64) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
/* |h0| <= 2^25 */
/* |h4| <= 2^25 */
/* |h1| <= 1.71*2^59 */
/* |h5| <= 1.71*2^59 */
carry1 = (h1 + (crypto_int64) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25;
carry5 = (h5 + (crypto_int64) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25;
/* |h1| <= 2^24; from now on fits into int32 */
/* |h5| <= 2^24; from now on fits into int32 */
/* |h2| <= 1.41*2^60 */
/* |h6| <= 1.41*2^60 */
carry2 = (h2 + (crypto_int64) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26;
carry6 = (h6 + (crypto_int64) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26;
/* |h2| <= 2^25; from now on fits into int32 unchanged */
/* |h6| <= 2^25; from now on fits into int32 unchanged */
/* |h3| <= 1.71*2^59 */
/* |h7| <= 1.71*2^59 */
carry3 = (h3 + (crypto_int64) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25;
carry7 = (h7 + (crypto_int64) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25;
/* |h3| <= 2^24; from now on fits into int32 unchanged */
/* |h7| <= 2^24; from now on fits into int32 unchanged */
/* |h4| <= 1.72*2^34 */
/* |h8| <= 1.41*2^60 */
carry4 = (h4 + (crypto_int64) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
carry8 = (h8 + (crypto_int64) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26;
/* |h4| <= 2^25; from now on fits into int32 unchanged */
/* |h8| <= 2^25; from now on fits into int32 unchanged */
/* |h5| <= 1.01*2^24 */
/* |h9| <= 1.71*2^59 */
carry9 = (h9 + (crypto_int64) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;
/* |h9| <= 2^24; from now on fits into int32 unchanged */
/* |h0| <= 1.1*2^39 */
carry0 = (h0 + (crypto_int64) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
/* |h0| <= 2^25; from now on fits into int32 unchanged */
/* |h1| <= 1.01*2^24 */
h[0] = h0;
h[1] = h1;
h[2] = h2;
h[3] = h3;
h[4] = h4;
h[5] = h5;
h[6] = h6;
h[7] = h7;
h[8] = h8;
h[9] = h9;
}

View File

@ -0,0 +1,45 @@
#include "fe.h"
/*
h = -f
Preconditions:
|f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
Postconditions:
|h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
*/
void fe_neg(fe h,const fe f)
{
crypto_int32 f0 = f[0];
crypto_int32 f1 = f[1];
crypto_int32 f2 = f[2];
crypto_int32 f3 = f[3];
crypto_int32 f4 = f[4];
crypto_int32 f5 = f[5];
crypto_int32 f6 = f[6];
crypto_int32 f7 = f[7];
crypto_int32 f8 = f[8];
crypto_int32 f9 = f[9];
crypto_int32 h0 = -f0;
crypto_int32 h1 = -f1;
crypto_int32 h2 = -f2;
crypto_int32 h3 = -f3;
crypto_int32 h4 = -f4;
crypto_int32 h5 = -f5;
crypto_int32 h6 = -f6;
crypto_int32 h7 = -f7;
crypto_int32 h8 = -f8;
crypto_int32 h9 = -f9;
h[0] = h0;
h[1] = h1;
h[2] = h2;
h[3] = h3;
h[4] = h4;
h[5] = h5;
h[6] = h6;
h[7] = h7;
h[8] = h8;
h[9] = h9;
}

View File

@ -0,0 +1,13 @@
#include "fe.h"
void fe_pow22523(fe out,const fe z)
{
fe t0;
fe t1;
fe t2;
int i;
#include "pow22523.h"
return;
}

View File

@ -0,0 +1,149 @@
#include "fe.h"
#include "crypto_int64.h"
/*
h = f * f
Can overlap h with f.
Preconditions:
|f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
Postconditions:
|h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.
*/
/*
See fe_mul.c for discussion of implementation strategy.
*/
void fe_sq(fe h,const fe f)
{
crypto_int32 f0 = f[0];
crypto_int32 f1 = f[1];
crypto_int32 f2 = f[2];
crypto_int32 f3 = f[3];
crypto_int32 f4 = f[4];
crypto_int32 f5 = f[5];
crypto_int32 f6 = f[6];
crypto_int32 f7 = f[7];
crypto_int32 f8 = f[8];
crypto_int32 f9 = f[9];
crypto_int32 f0_2 = 2 * f0;
crypto_int32 f1_2 = 2 * f1;
crypto_int32 f2_2 = 2 * f2;
crypto_int32 f3_2 = 2 * f3;
crypto_int32 f4_2 = 2 * f4;
crypto_int32 f5_2 = 2 * f5;
crypto_int32 f6_2 = 2 * f6;
crypto_int32 f7_2 = 2 * f7;
crypto_int32 f5_38 = 38 * f5; /* 1.959375*2^30 */
crypto_int32 f6_19 = 19 * f6; /* 1.959375*2^30 */
crypto_int32 f7_38 = 38 * f7; /* 1.959375*2^30 */
crypto_int32 f8_19 = 19 * f8; /* 1.959375*2^30 */
crypto_int32 f9_38 = 38 * f9; /* 1.959375*2^30 */
crypto_int64 f0f0 = f0 * (crypto_int64) f0;
crypto_int64 f0f1_2 = f0_2 * (crypto_int64) f1;
crypto_int64 f0f2_2 = f0_2 * (crypto_int64) f2;
crypto_int64 f0f3_2 = f0_2 * (crypto_int64) f3;
crypto_int64 f0f4_2 = f0_2 * (crypto_int64) f4;
crypto_int64 f0f5_2 = f0_2 * (crypto_int64) f5;
crypto_int64 f0f6_2 = f0_2 * (crypto_int64) f6;
crypto_int64 f0f7_2 = f0_2 * (crypto_int64) f7;
crypto_int64 f0f8_2 = f0_2 * (crypto_int64) f8;
crypto_int64 f0f9_2 = f0_2 * (crypto_int64) f9;
crypto_int64 f1f1_2 = f1_2 * (crypto_int64) f1;
crypto_int64 f1f2_2 = f1_2 * (crypto_int64) f2;
crypto_int64 f1f3_4 = f1_2 * (crypto_int64) f3_2;
crypto_int64 f1f4_2 = f1_2 * (crypto_int64) f4;
crypto_int64 f1f5_4 = f1_2 * (crypto_int64) f5_2;
crypto_int64 f1f6_2 = f1_2 * (crypto_int64) f6;
crypto_int64 f1f7_4 = f1_2 * (crypto_int64) f7_2;
crypto_int64 f1f8_2 = f1_2 * (crypto_int64) f8;
crypto_int64 f1f9_76 = f1_2 * (crypto_int64) f9_38;
crypto_int64 f2f2 = f2 * (crypto_int64) f2;
crypto_int64 f2f3_2 = f2_2 * (crypto_int64) f3;
crypto_int64 f2f4_2 = f2_2 * (crypto_int64) f4;
crypto_int64 f2f5_2 = f2_2 * (crypto_int64) f5;
crypto_int64 f2f6_2 = f2_2 * (crypto_int64) f6;
crypto_int64 f2f7_2 = f2_2 * (crypto_int64) f7;
crypto_int64 f2f8_38 = f2_2 * (crypto_int64) f8_19;
crypto_int64 f2f9_38 = f2 * (crypto_int64) f9_38;
crypto_int64 f3f3_2 = f3_2 * (crypto_int64) f3;
crypto_int64 f3f4_2 = f3_2 * (crypto_int64) f4;
crypto_int64 f3f5_4 = f3_2 * (crypto_int64) f5_2;
crypto_int64 f3f6_2 = f3_2 * (crypto_int64) f6;
crypto_int64 f3f7_76 = f3_2 * (crypto_int64) f7_38;
crypto_int64 f3f8_38 = f3_2 * (crypto_int64) f8_19;
crypto_int64 f3f9_76 = f3_2 * (crypto_int64) f9_38;
crypto_int64 f4f4 = f4 * (crypto_int64) f4;
crypto_int64 f4f5_2 = f4_2 * (crypto_int64) f5;
crypto_int64 f4f6_38 = f4_2 * (crypto_int64) f6_19;
crypto_int64 f4f7_38 = f4 * (crypto_int64) f7_38;
crypto_int64 f4f8_38 = f4_2 * (crypto_int64) f8_19;
crypto_int64 f4f9_38 = f4 * (crypto_int64) f9_38;
crypto_int64 f5f5_38 = f5 * (crypto_int64) f5_38;
crypto_int64 f5f6_38 = f5_2 * (crypto_int64) f6_19;
crypto_int64 f5f7_76 = f5_2 * (crypto_int64) f7_38;
crypto_int64 f5f8_38 = f5_2 * (crypto_int64) f8_19;
crypto_int64 f5f9_76 = f5_2 * (crypto_int64) f9_38;
crypto_int64 f6f6_19 = f6 * (crypto_int64) f6_19;
crypto_int64 f6f7_38 = f6 * (crypto_int64) f7_38;
crypto_int64 f6f8_38 = f6_2 * (crypto_int64) f8_19;
crypto_int64 f6f9_38 = f6 * (crypto_int64) f9_38;
crypto_int64 f7f7_38 = f7 * (crypto_int64) f7_38;
crypto_int64 f7f8_38 = f7_2 * (crypto_int64) f8_19;
crypto_int64 f7f9_76 = f7_2 * (crypto_int64) f9_38;
crypto_int64 f8f8_19 = f8 * (crypto_int64) f8_19;
crypto_int64 f8f9_38 = f8 * (crypto_int64) f9_38;
crypto_int64 f9f9_38 = f9 * (crypto_int64) f9_38;
crypto_int64 h0 = f0f0 +f1f9_76+f2f8_38+f3f7_76+f4f6_38+f5f5_38;
crypto_int64 h1 = f0f1_2+f2f9_38+f3f8_38+f4f7_38+f5f6_38;
crypto_int64 h2 = f0f2_2+f1f1_2 +f3f9_76+f4f8_38+f5f7_76+f6f6_19;
crypto_int64 h3 = f0f3_2+f1f2_2 +f4f9_38+f5f8_38+f6f7_38;
crypto_int64 h4 = f0f4_2+f1f3_4 +f2f2 +f5f9_76+f6f8_38+f7f7_38;
crypto_int64 h5 = f0f5_2+f1f4_2 +f2f3_2 +f6f9_38+f7f8_38;
crypto_int64 h6 = f0f6_2+f1f5_4 +f2f4_2 +f3f3_2 +f7f9_76+f8f8_19;
crypto_int64 h7 = f0f7_2+f1f6_2 +f2f5_2 +f3f4_2 +f8f9_38;
crypto_int64 h8 = f0f8_2+f1f7_4 +f2f6_2 +f3f5_4 +f4f4 +f9f9_38;
crypto_int64 h9 = f0f9_2+f1f8_2 +f2f7_2 +f3f6_2 +f4f5_2;
crypto_int64 carry0;
crypto_int64 carry1;
crypto_int64 carry2;
crypto_int64 carry3;
crypto_int64 carry4;
crypto_int64 carry5;
crypto_int64 carry6;
crypto_int64 carry7;
crypto_int64 carry8;
crypto_int64 carry9;
carry0 = (h0 + (crypto_int64) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
carry4 = (h4 + (crypto_int64) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
carry1 = (h1 + (crypto_int64) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25;
carry5 = (h5 + (crypto_int64) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25;
carry2 = (h2 + (crypto_int64) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26;
carry6 = (h6 + (crypto_int64) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26;
carry3 = (h3 + (crypto_int64) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25;
carry7 = (h7 + (crypto_int64) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25;
carry4 = (h4 + (crypto_int64) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
carry8 = (h8 + (crypto_int64) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26;
carry9 = (h9 + (crypto_int64) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;
carry0 = (h0 + (crypto_int64) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
h[0] = h0;
h[1] = h1;
h[2] = h2;
h[3] = h3;
h[4] = h4;
h[5] = h5;
h[6] = h6;
h[7] = h7;
h[8] = h8;
h[9] = h9;
}

View File

@ -0,0 +1,160 @@
#include "fe.h"
#include "crypto_int64.h"
/*
h = 2 * f * f
Can overlap h with f.
Preconditions:
|f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
Postconditions:
|h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.
*/
/*
See fe_mul.c for discussion of implementation strategy.
*/
void fe_sq2(fe h,const fe f)
{
crypto_int32 f0 = f[0];
crypto_int32 f1 = f[1];
crypto_int32 f2 = f[2];
crypto_int32 f3 = f[3];
crypto_int32 f4 = f[4];
crypto_int32 f5 = f[5];
crypto_int32 f6 = f[6];
crypto_int32 f7 = f[7];
crypto_int32 f8 = f[8];
crypto_int32 f9 = f[9];
crypto_int32 f0_2 = 2 * f0;
crypto_int32 f1_2 = 2 * f1;
crypto_int32 f2_2 = 2 * f2;
crypto_int32 f3_2 = 2 * f3;
crypto_int32 f4_2 = 2 * f4;
crypto_int32 f5_2 = 2 * f5;
crypto_int32 f6_2 = 2 * f6;
crypto_int32 f7_2 = 2 * f7;
crypto_int32 f5_38 = 38 * f5; /* 1.959375*2^30 */
crypto_int32 f6_19 = 19 * f6; /* 1.959375*2^30 */
crypto_int32 f7_38 = 38 * f7; /* 1.959375*2^30 */
crypto_int32 f8_19 = 19 * f8; /* 1.959375*2^30 */
crypto_int32 f9_38 = 38 * f9; /* 1.959375*2^30 */
crypto_int64 f0f0 = f0 * (crypto_int64) f0;
crypto_int64 f0f1_2 = f0_2 * (crypto_int64) f1;
crypto_int64 f0f2_2 = f0_2 * (crypto_int64) f2;
crypto_int64 f0f3_2 = f0_2 * (crypto_int64) f3;
crypto_int64 f0f4_2 = f0_2 * (crypto_int64) f4;
crypto_int64 f0f5_2 = f0_2 * (crypto_int64) f5;
crypto_int64 f0f6_2 = f0_2 * (crypto_int64) f6;
crypto_int64 f0f7_2 = f0_2 * (crypto_int64) f7;
crypto_int64 f0f8_2 = f0_2 * (crypto_int64) f8;
crypto_int64 f0f9_2 = f0_2 * (crypto_int64) f9;
crypto_int64 f1f1_2 = f1_2 * (crypto_int64) f1;
crypto_int64 f1f2_2 = f1_2 * (crypto_int64) f2;
crypto_int64 f1f3_4 = f1_2 * (crypto_int64) f3_2;
crypto_int64 f1f4_2 = f1_2 * (crypto_int64) f4;
crypto_int64 f1f5_4 = f1_2 * (crypto_int64) f5_2;
crypto_int64 f1f6_2 = f1_2 * (crypto_int64) f6;
crypto_int64 f1f7_4 = f1_2 * (crypto_int64) f7_2;
crypto_int64 f1f8_2 = f1_2 * (crypto_int64) f8;
crypto_int64 f1f9_76 = f1_2 * (crypto_int64) f9_38;
crypto_int64 f2f2 = f2 * (crypto_int64) f2;
crypto_int64 f2f3_2 = f2_2 * (crypto_int64) f3;
crypto_int64 f2f4_2 = f2_2 * (crypto_int64) f4;
crypto_int64 f2f5_2 = f2_2 * (crypto_int64) f5;
crypto_int64 f2f6_2 = f2_2 * (crypto_int64) f6;
crypto_int64 f2f7_2 = f2_2 * (crypto_int64) f7;
crypto_int64 f2f8_38 = f2_2 * (crypto_int64) f8_19;
crypto_int64 f2f9_38 = f2 * (crypto_int64) f9_38;
crypto_int64 f3f3_2 = f3_2 * (crypto_int64) f3;
crypto_int64 f3f4_2 = f3_2 * (crypto_int64) f4;
crypto_int64 f3f5_4 = f3_2 * (crypto_int64) f5_2;
crypto_int64 f3f6_2 = f3_2 * (crypto_int64) f6;
crypto_int64 f3f7_76 = f3_2 * (crypto_int64) f7_38;
crypto_int64 f3f8_38 = f3_2 * (crypto_int64) f8_19;
crypto_int64 f3f9_76 = f3_2 * (crypto_int64) f9_38;
crypto_int64 f4f4 = f4 * (crypto_int64) f4;
crypto_int64 f4f5_2 = f4_2 * (crypto_int64) f5;
crypto_int64 f4f6_38 = f4_2 * (crypto_int64) f6_19;
crypto_int64 f4f7_38 = f4 * (crypto_int64) f7_38;
crypto_int64 f4f8_38 = f4_2 * (crypto_int64) f8_19;
crypto_int64 f4f9_38 = f4 * (crypto_int64) f9_38;
crypto_int64 f5f5_38 = f5 * (crypto_int64) f5_38;
crypto_int64 f5f6_38 = f5_2 * (crypto_int64) f6_19;
crypto_int64 f5f7_76 = f5_2 * (crypto_int64) f7_38;
crypto_int64 f5f8_38 = f5_2 * (crypto_int64) f8_19;
crypto_int64 f5f9_76 = f5_2 * (crypto_int64) f9_38;
crypto_int64 f6f6_19 = f6 * (crypto_int64) f6_19;
crypto_int64 f6f7_38 = f6 * (crypto_int64) f7_38;
crypto_int64 f6f8_38 = f6_2 * (crypto_int64) f8_19;
crypto_int64 f6f9_38 = f6 * (crypto_int64) f9_38;
crypto_int64 f7f7_38 = f7 * (crypto_int64) f7_38;
crypto_int64 f7f8_38 = f7_2 * (crypto_int64) f8_19;
crypto_int64 f7f9_76 = f7_2 * (crypto_int64) f9_38;
crypto_int64 f8f8_19 = f8 * (crypto_int64) f8_19;
crypto_int64 f8f9_38 = f8 * (crypto_int64) f9_38;
crypto_int64 f9f9_38 = f9 * (crypto_int64) f9_38;
crypto_int64 h0 = f0f0 +f1f9_76+f2f8_38+f3f7_76+f4f6_38+f5f5_38;
crypto_int64 h1 = f0f1_2+f2f9_38+f3f8_38+f4f7_38+f5f6_38;
crypto_int64 h2 = f0f2_2+f1f1_2 +f3f9_76+f4f8_38+f5f7_76+f6f6_19;
crypto_int64 h3 = f0f3_2+f1f2_2 +f4f9_38+f5f8_38+f6f7_38;
crypto_int64 h4 = f0f4_2+f1f3_4 +f2f2 +f5f9_76+f6f8_38+f7f7_38;
crypto_int64 h5 = f0f5_2+f1f4_2 +f2f3_2 +f6f9_38+f7f8_38;
crypto_int64 h6 = f0f6_2+f1f5_4 +f2f4_2 +f3f3_2 +f7f9_76+f8f8_19;
crypto_int64 h7 = f0f7_2+f1f6_2 +f2f5_2 +f3f4_2 +f8f9_38;
crypto_int64 h8 = f0f8_2+f1f7_4 +f2f6_2 +f3f5_4 +f4f4 +f9f9_38;
crypto_int64 h9 = f0f9_2+f1f8_2 +f2f7_2 +f3f6_2 +f4f5_2;
crypto_int64 carry0;
crypto_int64 carry1;
crypto_int64 carry2;
crypto_int64 carry3;
crypto_int64 carry4;
crypto_int64 carry5;
crypto_int64 carry6;
crypto_int64 carry7;
crypto_int64 carry8;
crypto_int64 carry9;
h0 += h0;
h1 += h1;
h2 += h2;
h3 += h3;
h4 += h4;
h5 += h5;
h6 += h6;
h7 += h7;
h8 += h8;
h9 += h9;
carry0 = (h0 + (crypto_int64) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
carry4 = (h4 + (crypto_int64) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
carry1 = (h1 + (crypto_int64) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25;
carry5 = (h5 + (crypto_int64) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25;
carry2 = (h2 + (crypto_int64) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26;
carry6 = (h6 + (crypto_int64) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26;
carry3 = (h3 + (crypto_int64) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25;
carry7 = (h7 + (crypto_int64) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25;
carry4 = (h4 + (crypto_int64) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
carry8 = (h8 + (crypto_int64) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26;
carry9 = (h9 + (crypto_int64) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;
carry0 = (h0 + (crypto_int64) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
h[0] = h0;
h[1] = h1;
h[2] = h2;
h[3] = h3;
h[4] = h4;
h[5] = h5;
h[6] = h6;
h[7] = h7;
h[8] = h8;
h[9] = h9;
}

View File

@ -0,0 +1,57 @@
#include "fe.h"
/*
h = f - g
Can overlap h with f or g.
Preconditions:
|f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
|g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
Postconditions:
|h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
*/
void fe_sub(fe h,const fe f,const fe g)
{
crypto_int32 f0 = f[0];
crypto_int32 f1 = f[1];
crypto_int32 f2 = f[2];
crypto_int32 f3 = f[3];
crypto_int32 f4 = f[4];
crypto_int32 f5 = f[5];
crypto_int32 f6 = f[6];
crypto_int32 f7 = f[7];
crypto_int32 f8 = f[8];
crypto_int32 f9 = f[9];
crypto_int32 g0 = g[0];
crypto_int32 g1 = g[1];
crypto_int32 g2 = g[2];
crypto_int32 g3 = g[3];
crypto_int32 g4 = g[4];
crypto_int32 g5 = g[5];
crypto_int32 g6 = g[6];
crypto_int32 g7 = g[7];
crypto_int32 g8 = g[8];
crypto_int32 g9 = g[9];
crypto_int32 h0 = f0 - g0;
crypto_int32 h1 = f1 - g1;
crypto_int32 h2 = f2 - g2;
crypto_int32 h3 = f3 - g3;
crypto_int32 h4 = f4 - g4;
crypto_int32 h5 = f5 - g5;
crypto_int32 h6 = f6 - g6;
crypto_int32 h7 = f7 - g7;
crypto_int32 h8 = f8 - g8;
crypto_int32 h9 = f9 - g9;
h[0] = h0;
h[1] = h1;
h[2] = h2;
h[3] = h3;
h[4] = h4;
h[5] = h5;
h[6] = h6;
h[7] = h7;
h[8] = h8;
h[9] = h9;
}

View File

@ -0,0 +1,119 @@
#include "fe.h"
/*
Preconditions:
|h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
Write p=2^255-19; q=floor(h/p).
Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))).
Proof:
Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4.
Also have |h-2^230 h9|<2^231 so |19 2^(-255)(h-2^230 h9)|<1/4.
Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9).
Then 0<y<1.
Write r=h-pq.
Have 0<=r<=p-1=2^255-20.
Thus 0<=r+19(2^-255)r<r+19(2^-255)2^255<=2^255-1.
Write x=r+19(2^-255)r+y.
Then 0<x<2^255 so floor(2^(-255)x) = 0 so floor(q+2^(-255)x) = q.
Have q+2^(-255)x = 2^(-255)(h + 19 2^(-25) h9 + 2^(-1))
so floor(2^(-255)(h + 19 2^(-25) h9 + 2^(-1))) = q.
*/
void fe_tobytes(unsigned char *s,const fe h)
{
crypto_int32 h0 = h[0];
crypto_int32 h1 = h[1];
crypto_int32 h2 = h[2];
crypto_int32 h3 = h[3];
crypto_int32 h4 = h[4];
crypto_int32 h5 = h[5];
crypto_int32 h6 = h[6];
crypto_int32 h7 = h[7];
crypto_int32 h8 = h[8];
crypto_int32 h9 = h[9];
crypto_int32 q;
crypto_int32 carry0;
crypto_int32 carry1;
crypto_int32 carry2;
crypto_int32 carry3;
crypto_int32 carry4;
crypto_int32 carry5;
crypto_int32 carry6;
crypto_int32 carry7;
crypto_int32 carry8;
crypto_int32 carry9;
q = (19 * h9 + (((crypto_int32) 1) << 24)) >> 25;
q = (h0 + q) >> 26;
q = (h1 + q) >> 25;
q = (h2 + q) >> 26;
q = (h3 + q) >> 25;
q = (h4 + q) >> 26;
q = (h5 + q) >> 25;
q = (h6 + q) >> 26;
q = (h7 + q) >> 25;
q = (h8 + q) >> 26;
q = (h9 + q) >> 25;
/* Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. */
h0 += 19 * q;
/* Goal: Output h-2^255 q, which is between 0 and 2^255-20. */
carry0 = h0 >> 26; h1 += carry0; h0 -= carry0 << 26;
carry1 = h1 >> 25; h2 += carry1; h1 -= carry1 << 25;
carry2 = h2 >> 26; h3 += carry2; h2 -= carry2 << 26;
carry3 = h3 >> 25; h4 += carry3; h3 -= carry3 << 25;
carry4 = h4 >> 26; h5 += carry4; h4 -= carry4 << 26;
carry5 = h5 >> 25; h6 += carry5; h5 -= carry5 << 25;
carry6 = h6 >> 26; h7 += carry6; h6 -= carry6 << 26;
carry7 = h7 >> 25; h8 += carry7; h7 -= carry7 << 25;
carry8 = h8 >> 26; h9 += carry8; h8 -= carry8 << 26;
carry9 = h9 >> 25; h9 -= carry9 << 25;
/* h10 = carry9 */
/*
Goal: Output h0+...+2^255 h10-2^255 q, which is between 0 and 2^255-20.
Have h0+...+2^230 h9 between 0 and 2^255-1;
evidently 2^255 h10-2^255 q = 0.
Goal: Output h0+...+2^230 h9.
*/
s[0] = h0 >> 0;
s[1] = h0 >> 8;
s[2] = h0 >> 16;
s[3] = (h0 >> 24) | (h1 << 2);
s[4] = h1 >> 6;
s[5] = h1 >> 14;
s[6] = (h1 >> 22) | (h2 << 3);
s[7] = h2 >> 5;
s[8] = h2 >> 13;
s[9] = (h2 >> 21) | (h3 << 5);
s[10] = h3 >> 3;
s[11] = h3 >> 11;
s[12] = (h3 >> 19) | (h4 << 6);
s[13] = h4 >> 2;
s[14] = h4 >> 10;
s[15] = h4 >> 18;
s[16] = h5 >> 0;
s[17] = h5 >> 8;
s[18] = h5 >> 16;
s[19] = (h5 >> 24) | (h6 << 1);
s[20] = h6 >> 7;
s[21] = h6 >> 15;
s[22] = (h6 >> 23) | (h7 << 3);
s[23] = h7 >> 5;
s[24] = h7 >> 13;
s[25] = (h7 >> 21) | (h8 << 4);
s[26] = h8 >> 4;
s[27] = h8 >> 12;
s[28] = (h8 >> 20) | (h9 << 6);
s[29] = h9 >> 2;
s[30] = h9 >> 10;
s[31] = h9 >> 18;
}

95
core/crypto/ed25519/ge.h Normal file
View File

@ -0,0 +1,95 @@
#ifndef GE_H
#define GE_H
/*
ge means group element.
Here the group is the set of pairs (x,y) of field elements (see fe.h)
satisfying -x^2 + y^2 = 1 + d x^2y^2
where d = -121665/121666.
Representations:
ge_p2 (projective): (X:Y:Z) satisfying x=X/Z, y=Y/Z
ge_p3 (extended): (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT
ge_p1p1 (completed): ((X:Z),(Y:T)) satisfying x=X/Z, y=Y/T
ge_precomp (Duif): (y+x,y-x,2dxy)
*/
#include "fe.h"
typedef struct {
fe X;
fe Y;
fe Z;
} ge_p2;
typedef struct {
fe X;
fe Y;
fe Z;
fe T;
} ge_p3;
typedef struct {
fe X;
fe Y;
fe Z;
fe T;
} ge_p1p1;
typedef struct {
fe yplusx;
fe yminusx;
fe xy2d;
} ge_precomp;
typedef struct {
fe YplusX;
fe YminusX;
fe Z;
fe T2d;
} ge_cached;
#define ge_frombytes_negate_vartime crypto_sign_ed25519_ref10_ge_frombytes_negate_vartime
#define ge_tobytes crypto_sign_ed25519_ref10_ge_tobytes
#define ge_p3_tobytes crypto_sign_ed25519_ref10_ge_p3_tobytes
#define ge_p2_0 crypto_sign_ed25519_ref10_ge_p2_0
#define ge_p3_0 crypto_sign_ed25519_ref10_ge_p3_0
#define ge_precomp_0 crypto_sign_ed25519_ref10_ge_precomp_0
#define ge_p3_to_p2 crypto_sign_ed25519_ref10_ge_p3_to_p2
#define ge_p3_to_cached crypto_sign_ed25519_ref10_ge_p3_to_cached
#define ge_p1p1_to_p2 crypto_sign_ed25519_ref10_ge_p1p1_to_p2
#define ge_p1p1_to_p3 crypto_sign_ed25519_ref10_ge_p1p1_to_p3
#define ge_p2_dbl crypto_sign_ed25519_ref10_ge_p2_dbl
#define ge_p3_dbl crypto_sign_ed25519_ref10_ge_p3_dbl
#define ge_madd crypto_sign_ed25519_ref10_ge_madd
#define ge_msub crypto_sign_ed25519_ref10_ge_msub
#define ge_add crypto_sign_ed25519_ref10_ge_add
#define ge_sub crypto_sign_ed25519_ref10_ge_sub
#define ge_scalarmult_base crypto_sign_ed25519_ref10_ge_scalarmult_base
#define ge_double_scalarmult_vartime crypto_sign_ed25519_ref10_ge_double_scalarmult_vartime
extern void ge_tobytes(unsigned char *,const ge_p2 *);
extern void ge_p3_tobytes(unsigned char *,const ge_p3 *);
extern int ge_frombytes_negate_vartime(ge_p3 *,const unsigned char *);
extern void ge_p2_0(ge_p2 *);
extern void ge_p3_0(ge_p3 *);
extern void ge_precomp_0(ge_precomp *);
extern void ge_p3_to_p2(ge_p2 *,const ge_p3 *);
extern void ge_p3_to_cached(ge_cached *,const ge_p3 *);
extern void ge_p1p1_to_p2(ge_p2 *,const ge_p1p1 *);
extern void ge_p1p1_to_p3(ge_p3 *,const ge_p1p1 *);
extern void ge_p2_dbl(ge_p1p1 *,const ge_p2 *);
extern void ge_p3_dbl(ge_p1p1 *,const ge_p3 *);
extern void ge_madd(ge_p1p1 *,const ge_p3 *,const ge_precomp *);
extern void ge_msub(ge_p1p1 *,const ge_p3 *,const ge_precomp *);
extern void ge_add(ge_p1p1 *,const ge_p3 *,const ge_cached *);
extern void ge_sub(ge_p1p1 *,const ge_p3 *,const ge_cached *);
extern void ge_scalarmult_base(ge_p3 *,const unsigned char *);
extern void ge_double_scalarmult_vartime(ge_p2 *,const unsigned char *,const ge_p3 *,const unsigned char *);
#endif

View File

@ -0,0 +1,11 @@
#include "ge.h"
/*
r = p + q
*/
void ge_add(ge_p1p1 *r,const ge_p3 *p,const ge_cached *q)
{
fe t0;
#include "ge_add.h"
}

View File

@ -0,0 +1,97 @@
/* qhasm: enter ge_add */
/* qhasm: fe X1 */
/* qhasm: fe Y1 */
/* qhasm: fe Z1 */
/* qhasm: fe Z2 */
/* qhasm: fe T1 */
/* qhasm: fe ZZ */
/* qhasm: fe YpX2 */
/* qhasm: fe YmX2 */
/* qhasm: fe T2d2 */
/* qhasm: fe X3 */
/* qhasm: fe Y3 */
/* qhasm: fe Z3 */
/* qhasm: fe T3 */
/* qhasm: fe YpX1 */
/* qhasm: fe YmX1 */
/* qhasm: fe A */
/* qhasm: fe B */
/* qhasm: fe C */
/* qhasm: fe D */
/* qhasm: YpX1 = Y1+X1 */
/* asm 1: fe_add(>YpX1=fe#1,<Y1=fe#12,<X1=fe#11); */
/* asm 2: fe_add(>YpX1=r->X,<Y1=p->Y,<X1=p->X); */
fe_add(r->X,p->Y,p->X);
/* qhasm: YmX1 = Y1-X1 */
/* asm 1: fe_sub(>YmX1=fe#2,<Y1=fe#12,<X1=fe#11); */
/* asm 2: fe_sub(>YmX1=r->Y,<Y1=p->Y,<X1=p->X); */
fe_sub(r->Y,p->Y,p->X);
/* qhasm: A = YpX1*YpX2 */
/* asm 1: fe_mul(>A=fe#3,<YpX1=fe#1,<YpX2=fe#15); */
/* asm 2: fe_mul(>A=r->Z,<YpX1=r->X,<YpX2=q->YplusX); */
fe_mul(r->Z,r->X,q->YplusX);
/* qhasm: B = YmX1*YmX2 */
/* asm 1: fe_mul(>B=fe#2,<YmX1=fe#2,<YmX2=fe#16); */
/* asm 2: fe_mul(>B=r->Y,<YmX1=r->Y,<YmX2=q->YminusX); */
fe_mul(r->Y,r->Y,q->YminusX);
/* qhasm: C = T2d2*T1 */
/* asm 1: fe_mul(>C=fe#4,<T2d2=fe#18,<T1=fe#14); */
/* asm 2: fe_mul(>C=r->T,<T2d2=q->T2d,<T1=p->T); */
fe_mul(r->T,q->T2d,p->T);
/* qhasm: ZZ = Z1*Z2 */
/* asm 1: fe_mul(>ZZ=fe#1,<Z1=fe#13,<Z2=fe#17); */
/* asm 2: fe_mul(>ZZ=r->X,<Z1=p->Z,<Z2=q->Z); */
fe_mul(r->X,p->Z,q->Z);
/* qhasm: D = 2*ZZ */
/* asm 1: fe_add(>D=fe#5,<ZZ=fe#1,<ZZ=fe#1); */
/* asm 2: fe_add(>D=t0,<ZZ=r->X,<ZZ=r->X); */
fe_add(t0,r->X,r->X);
/* qhasm: X3 = A-B */
/* asm 1: fe_sub(>X3=fe#1,<A=fe#3,<B=fe#2); */
/* asm 2: fe_sub(>X3=r->X,<A=r->Z,<B=r->Y); */
fe_sub(r->X,r->Z,r->Y);
/* qhasm: Y3 = A+B */
/* asm 1: fe_add(>Y3=fe#2,<A=fe#3,<B=fe#2); */
/* asm 2: fe_add(>Y3=r->Y,<A=r->Z,<B=r->Y); */
fe_add(r->Y,r->Z,r->Y);
/* qhasm: Z3 = D+C */
/* asm 1: fe_add(>Z3=fe#3,<D=fe#5,<C=fe#4); */
/* asm 2: fe_add(>Z3=r->Z,<D=t0,<C=r->T); */
fe_add(r->Z,t0,r->T);
/* qhasm: T3 = D-C */
/* asm 1: fe_sub(>T3=fe#4,<D=fe#5,<C=fe#4); */
/* asm 2: fe_sub(>T3=r->T,<D=t0,<C=r->T); */
fe_sub(r->T,t0,r->T);
/* qhasm: return */

View File

@ -0,0 +1,49 @@
:name:fe:r->X:r->Y:r->Z:r->T:t0:t1:t2:t3:t4:t5:p->X:p->Y:p->Z:p->T:q->YplusX:q->YminusX:q->Z:q->T2d:
fe r:var/r=fe:
enter f:enter/f:>X1=fe#11:>Y1=fe#12:>Z1=fe#13:>T1=fe#14:>YpX2=fe#15:>YmX2=fe#16:>Z2=fe#17:>T2d2=fe#18:
return:nofallthrough:<X3=fe#1:<Y3=fe#2:<Z3=fe#3:<T3=fe#4:leave:
h=f+g:<f=fe:<g=fe:>h=fe:asm/fe_add(>h,<f,<g);:
h=f-g:<f=fe:<g=fe:>h=fe:asm/fe_sub(>h,<f,<g);:
h=f*g:<f=fe:<g=fe:>h=fe:asm/fe_mul(>h,<f,<g);:
h=f^2:<f=fe:>h=fe:asm/fe_sq(>h,<f);:
h=2*g:<g=fe:>h=fe:asm/fe_add(>h,<g,<g);:
:
enter ge_add
fe X1
fe Y1
fe Z1
fe Z2
fe T1
fe ZZ
fe YpX2
fe YmX2
fe T2d2
fe X3
fe Y3
fe Z3
fe T3
fe YpX1
fe YmX1
fe A
fe B
fe C
fe D
YpX1 = Y1+X1
YmX1 = Y1-X1
A = YpX1*YpX2
B = YmX1*YmX2
C = T2d2*T1
ZZ = Z1*Z2
D = 2*ZZ
X3 = A-B
Y3 = A+B
Z3 = D+C
T3 = D-C
return

View File

@ -0,0 +1,96 @@
#include "ge.h"
static void slide(signed char *r,const unsigned char *a)
{
int i;
int b;
int k;
for (i = 0;i < 256;++i)
r[i] = 1 & (a[i >> 3] >> (i & 7));
for (i = 0;i < 256;++i)
if (r[i]) {
for (b = 1;b <= 6 && i + b < 256;++b) {
if (r[i + b]) {
if (r[i] + (r[i + b] << b) <= 15) {
r[i] += r[i + b] << b; r[i + b] = 0;
} else if (r[i] - (r[i + b] << b) >= -15) {
r[i] -= r[i + b] << b;
for (k = i + b;k < 256;++k) {
if (!r[k]) {
r[k] = 1;
break;
}
r[k] = 0;
}
} else
break;
}
}
}
}
static ge_precomp Bi[8] = {
#include "base2.h"
} ;
/*
r = a * A + b * B
where a = a[0]+256*a[1]+...+256^31 a[31].
and b = b[0]+256*b[1]+...+256^31 b[31].
B is the Ed25519 base point (x,4/5) with x positive.
*/
void ge_double_scalarmult_vartime(ge_p2 *r,const unsigned char *a,const ge_p3 *A,const unsigned char *b)
{
signed char aslide[256];
signed char bslide[256];
ge_cached Ai[8]; /* A,3A,5A,7A,9A,11A,13A,15A */
ge_p1p1 t;
ge_p3 u;
ge_p3 A2;
int i;
slide(aslide,a);
slide(bslide,b);
ge_p3_to_cached(&Ai[0],A);
ge_p3_dbl(&t,A); ge_p1p1_to_p3(&A2,&t);
ge_add(&t,&A2,&Ai[0]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[1],&u);
ge_add(&t,&A2,&Ai[1]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[2],&u);
ge_add(&t,&A2,&Ai[2]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[3],&u);
ge_add(&t,&A2,&Ai[3]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[4],&u);
ge_add(&t,&A2,&Ai[4]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[5],&u);
ge_add(&t,&A2,&Ai[5]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[6],&u);
ge_add(&t,&A2,&Ai[6]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[7],&u);
ge_p2_0(r);
for (i = 255;i >= 0;--i) {
if (aslide[i] || bslide[i]) break;
}
for (;i >= 0;--i) {
ge_p2_dbl(&t,r);
if (aslide[i] > 0) {
ge_p1p1_to_p3(&u,&t);
ge_add(&t,&u,&Ai[aslide[i]/2]);
} else if (aslide[i] < 0) {
ge_p1p1_to_p3(&u,&t);
ge_sub(&t,&u,&Ai[(-aslide[i])/2]);
}
if (bslide[i] > 0) {
ge_p1p1_to_p3(&u,&t);
ge_madd(&t,&u,&Bi[bslide[i]/2]);
} else if (bslide[i] < 0) {
ge_p1p1_to_p3(&u,&t);
ge_msub(&t,&u,&Bi[(-bslide[i])/2]);
}
ge_p1p1_to_p2(r,&t);
}
}

View File

@ -0,0 +1,50 @@
#include "ge.h"
static const fe d = {
#include "d.h"
} ;
static const fe sqrtm1 = {
#include "sqrtm1.h"
} ;
int ge_frombytes_negate_vartime(ge_p3 *h,const unsigned char *s)
{
fe u;
fe v;
fe v3;
fe vxx;
fe check;
fe_frombytes(h->Y,s);
fe_1(h->Z);
fe_sq(u,h->Y);
fe_mul(v,u,d);
fe_sub(u,u,h->Z); /* u = y^2-1 */
fe_add(v,v,h->Z); /* v = dy^2+1 */
fe_sq(v3,v);
fe_mul(v3,v3,v); /* v3 = v^3 */
fe_sq(h->X,v3);
fe_mul(h->X,h->X,v);
fe_mul(h->X,h->X,u); /* x = uv^7 */
fe_pow22523(h->X,h->X); /* x = (uv^7)^((q-5)/8) */
fe_mul(h->X,h->X,v3);
fe_mul(h->X,h->X,u); /* x = uv^3(uv^7)^((q-5)/8) */
fe_sq(vxx,h->X);
fe_mul(vxx,vxx,v);
fe_sub(check,vxx,u); /* vx^2-u */
if (fe_isnonzero(check)) {
fe_add(check,vxx,u); /* vx^2+u */
if (fe_isnonzero(check)) return -1;
fe_mul(h->X,h->X,sqrtm1);
}
if (fe_isnegative(h->X) == (s[31] >> 7))
fe_neg(h->X,h->X);
fe_mul(h->T,h->X,h->Y);
return 0;
}

View File

@ -0,0 +1,11 @@
#include "ge.h"
/*
r = p + q
*/
void ge_madd(ge_p1p1 *r,const ge_p3 *p,const ge_precomp *q)
{
fe t0;
#include "ge_madd.h"
}

View File

@ -0,0 +1,88 @@
/* qhasm: enter ge_madd */
/* qhasm: fe X1 */
/* qhasm: fe Y1 */
/* qhasm: fe Z1 */
/* qhasm: fe T1 */
/* qhasm: fe ypx2 */
/* qhasm: fe ymx2 */
/* qhasm: fe xy2d2 */
/* qhasm: fe X3 */
/* qhasm: fe Y3 */
/* qhasm: fe Z3 */
/* qhasm: fe T3 */
/* qhasm: fe YpX1 */
/* qhasm: fe YmX1 */
/* qhasm: fe A */
/* qhasm: fe B */
/* qhasm: fe C */
/* qhasm: fe D */
/* qhasm: YpX1 = Y1+X1 */
/* asm 1: fe_add(>YpX1=fe#1,<Y1=fe#12,<X1=fe#11); */
/* asm 2: fe_add(>YpX1=r->X,<Y1=p->Y,<X1=p->X); */
fe_add(r->X,p->Y,p->X);
/* qhasm: YmX1 = Y1-X1 */
/* asm 1: fe_sub(>YmX1=fe#2,<Y1=fe#12,<X1=fe#11); */
/* asm 2: fe_sub(>YmX1=r->Y,<Y1=p->Y,<X1=p->X); */
fe_sub(r->Y,p->Y,p->X);
/* qhasm: A = YpX1*ypx2 */
/* asm 1: fe_mul(>A=fe#3,<YpX1=fe#1,<ypx2=fe#15); */
/* asm 2: fe_mul(>A=r->Z,<YpX1=r->X,<ypx2=q->yplusx); */
fe_mul(r->Z,r->X,q->yplusx);
/* qhasm: B = YmX1*ymx2 */
/* asm 1: fe_mul(>B=fe#2,<YmX1=fe#2,<ymx2=fe#16); */
/* asm 2: fe_mul(>B=r->Y,<YmX1=r->Y,<ymx2=q->yminusx); */
fe_mul(r->Y,r->Y,q->yminusx);
/* qhasm: C = xy2d2*T1 */
/* asm 1: fe_mul(>C=fe#4,<xy2d2=fe#17,<T1=fe#14); */
/* asm 2: fe_mul(>C=r->T,<xy2d2=q->xy2d,<T1=p->T); */
fe_mul(r->T,q->xy2d,p->T);
/* qhasm: D = 2*Z1 */
/* asm 1: fe_add(>D=fe#5,<Z1=fe#13,<Z1=fe#13); */
/* asm 2: fe_add(>D=t0,<Z1=p->Z,<Z1=p->Z); */
fe_add(t0,p->Z,p->Z);
/* qhasm: X3 = A-B */
/* asm 1: fe_sub(>X3=fe#1,<A=fe#3,<B=fe#2); */
/* asm 2: fe_sub(>X3=r->X,<A=r->Z,<B=r->Y); */
fe_sub(r->X,r->Z,r->Y);
/* qhasm: Y3 = A+B */
/* asm 1: fe_add(>Y3=fe#2,<A=fe#3,<B=fe#2); */
/* asm 2: fe_add(>Y3=r->Y,<A=r->Z,<B=r->Y); */
fe_add(r->Y,r->Z,r->Y);
/* qhasm: Z3 = D+C */
/* asm 1: fe_add(>Z3=fe#3,<D=fe#5,<C=fe#4); */
/* asm 2: fe_add(>Z3=r->Z,<D=t0,<C=r->T); */
fe_add(r->Z,t0,r->T);
/* qhasm: T3 = D-C */
/* asm 1: fe_sub(>T3=fe#4,<D=fe#5,<C=fe#4); */
/* asm 2: fe_sub(>T3=r->T,<D=t0,<C=r->T); */
fe_sub(r->T,t0,r->T);
/* qhasm: return */

View File

@ -0,0 +1,46 @@
:name:fe:r->X:r->Y:r->Z:r->T:t0:t1:t2:t3:t4:t5:p->X:p->Y:p->Z:p->T:q->yplusx:q->yminusx:q->xy2d:
fe r:var/r=fe:
enter f:enter/f:>X1=fe#11:>Y1=fe#12:>Z1=fe#13:>T1=fe#14:>ypx2=fe#15:>ymx2=fe#16:>xy2d2=fe#17:
return:nofallthrough:<X3=fe#1:<Y3=fe#2:<Z3=fe#3:<T3=fe#4:leave:
h=f+g:<f=fe:<g=fe:>h=fe:asm/fe_add(>h,<f,<g);:
h=f-g:<f=fe:<g=fe:>h=fe:asm/fe_sub(>h,<f,<g);:
h=f*g:<f=fe:<g=fe:>h=fe:asm/fe_mul(>h,<f,<g);:
h=f^2:<f=fe:>h=fe:asm/fe_sq(>h,<f);:
h=2*g:<g=fe:>h=fe:asm/fe_add(>h,<g,<g);:
:
enter ge_madd
fe X1
fe Y1
fe Z1
fe T1
fe ypx2
fe ymx2
fe xy2d2
fe X3
fe Y3
fe Z3
fe T3
fe YpX1
fe YmX1
fe A
fe B
fe C
fe D
YpX1 = Y1+X1
YmX1 = Y1-X1
A = YpX1*ypx2
B = YmX1*ymx2
C = xy2d2*T1
D = 2*Z1
X3 = A-B
Y3 = A+B
Z3 = D+C
T3 = D-C
return

View File

@ -0,0 +1,11 @@
#include "ge.h"
/*
r = p - q
*/
void ge_msub(ge_p1p1 *r,const ge_p3 *p,const ge_precomp *q)
{
fe t0;
#include "ge_msub.h"
}

View File

@ -0,0 +1,88 @@
/* qhasm: enter ge_msub */
/* qhasm: fe X1 */
/* qhasm: fe Y1 */
/* qhasm: fe Z1 */
/* qhasm: fe T1 */
/* qhasm: fe ypx2 */
/* qhasm: fe ymx2 */
/* qhasm: fe xy2d2 */
/* qhasm: fe X3 */
/* qhasm: fe Y3 */
/* qhasm: fe Z3 */
/* qhasm: fe T3 */
/* qhasm: fe YpX1 */
/* qhasm: fe YmX1 */
/* qhasm: fe A */
/* qhasm: fe B */
/* qhasm: fe C */
/* qhasm: fe D */
/* qhasm: YpX1 = Y1+X1 */
/* asm 1: fe_add(>YpX1=fe#1,<Y1=fe#12,<X1=fe#11); */
/* asm 2: fe_add(>YpX1=r->X,<Y1=p->Y,<X1=p->X); */
fe_add(r->X,p->Y,p->X);
/* qhasm: YmX1 = Y1-X1 */
/* asm 1: fe_sub(>YmX1=fe#2,<Y1=fe#12,<X1=fe#11); */
/* asm 2: fe_sub(>YmX1=r->Y,<Y1=p->Y,<X1=p->X); */
fe_sub(r->Y,p->Y,p->X);
/* qhasm: A = YpX1*ymx2 */
/* asm 1: fe_mul(>A=fe#3,<YpX1=fe#1,<ymx2=fe#16); */
/* asm 2: fe_mul(>A=r->Z,<YpX1=r->X,<ymx2=q->yminusx); */
fe_mul(r->Z,r->X,q->yminusx);
/* qhasm: B = YmX1*ypx2 */
/* asm 1: fe_mul(>B=fe#2,<YmX1=fe#2,<ypx2=fe#15); */
/* asm 2: fe_mul(>B=r->Y,<YmX1=r->Y,<ypx2=q->yplusx); */
fe_mul(r->Y,r->Y,q->yplusx);
/* qhasm: C = xy2d2*T1 */
/* asm 1: fe_mul(>C=fe#4,<xy2d2=fe#17,<T1=fe#14); */
/* asm 2: fe_mul(>C=r->T,<xy2d2=q->xy2d,<T1=p->T); */
fe_mul(r->T,q->xy2d,p->T);
/* qhasm: D = 2*Z1 */
/* asm 1: fe_add(>D=fe#5,<Z1=fe#13,<Z1=fe#13); */
/* asm 2: fe_add(>D=t0,<Z1=p->Z,<Z1=p->Z); */
fe_add(t0,p->Z,p->Z);
/* qhasm: X3 = A-B */
/* asm 1: fe_sub(>X3=fe#1,<A=fe#3,<B=fe#2); */
/* asm 2: fe_sub(>X3=r->X,<A=r->Z,<B=r->Y); */
fe_sub(r->X,r->Z,r->Y);
/* qhasm: Y3 = A+B */
/* asm 1: fe_add(>Y3=fe#2,<A=fe#3,<B=fe#2); */
/* asm 2: fe_add(>Y3=r->Y,<A=r->Z,<B=r->Y); */
fe_add(r->Y,r->Z,r->Y);
/* qhasm: Z3 = D-C */
/* asm 1: fe_sub(>Z3=fe#3,<D=fe#5,<C=fe#4); */
/* asm 2: fe_sub(>Z3=r->Z,<D=t0,<C=r->T); */
fe_sub(r->Z,t0,r->T);
/* qhasm: T3 = D+C */
/* asm 1: fe_add(>T3=fe#4,<D=fe#5,<C=fe#4); */
/* asm 2: fe_add(>T3=r->T,<D=t0,<C=r->T); */
fe_add(r->T,t0,r->T);
/* qhasm: return */

View File

@ -0,0 +1,46 @@
:name:fe:r->X:r->Y:r->Z:r->T:t0:t1:t2:t3:t4:t5:p->X:p->Y:p->Z:p->T:q->yplusx:q->yminusx:q->xy2d:
fe r:var/r=fe:
enter f:enter/f:>X1=fe#11:>Y1=fe#12:>Z1=fe#13:>T1=fe#14:>ypx2=fe#15:>ymx2=fe#16:>xy2d2=fe#17:
return:nofallthrough:<X3=fe#1:<Y3=fe#2:<Z3=fe#3:<T3=fe#4:leave:
h=f+g:<f=fe:<g=fe:>h=fe:asm/fe_add(>h,<f,<g);:
h=f-g:<f=fe:<g=fe:>h=fe:asm/fe_sub(>h,<f,<g);:
h=f*g:<f=fe:<g=fe:>h=fe:asm/fe_mul(>h,<f,<g);:
h=f^2:<f=fe:>h=fe:asm/fe_sq(>h,<f);:
h=2*g:<g=fe:>h=fe:asm/fe_add(>h,<g,<g);:
:
enter ge_msub
fe X1
fe Y1
fe Z1
fe T1
fe ypx2
fe ymx2
fe xy2d2
fe X3
fe Y3
fe Z3
fe T3
fe YpX1
fe YmX1
fe A
fe B
fe C
fe D
YpX1 = Y1+X1
YmX1 = Y1-X1
A = YpX1*ymx2
B = YmX1*ypx2
C = xy2d2*T1
D = 2*Z1
X3 = A-B
Y3 = A+B
Z3 = D-C
T3 = D+C
return

View File

@ -0,0 +1,12 @@
#include "ge.h"
/*
r = p
*/
extern void ge_p1p1_to_p2(ge_p2 *r,const ge_p1p1 *p)
{
fe_mul(r->X,p->X,p->T);
fe_mul(r->Y,p->Y,p->Z);
fe_mul(r->Z,p->Z,p->T);
}

View File

@ -0,0 +1,13 @@
#include "ge.h"
/*
r = p
*/
extern void ge_p1p1_to_p3(ge_p3 *r,const ge_p1p1 *p)
{
fe_mul(r->X,p->X,p->T);
fe_mul(r->Y,p->Y,p->Z);
fe_mul(r->Z,p->Z,p->T);
fe_mul(r->T,p->X,p->Y);
}

View File

@ -0,0 +1,8 @@
#include "ge.h"
void ge_p2_0(ge_p2 *h)
{
fe_0(h->X);
fe_1(h->Y);
fe_1(h->Z);
}

View File

@ -0,0 +1,11 @@
#include "ge.h"
/*
r = 2 * p
*/
void ge_p2_dbl(ge_p1p1 *r,const ge_p2 *p)
{
fe t0;
#include "ge_p2_dbl.h"
}

View File

@ -0,0 +1,73 @@
/* qhasm: enter ge_p2_dbl */
/* qhasm: fe X1 */
/* qhasm: fe Y1 */
/* qhasm: fe Z1 */
/* qhasm: fe A */
/* qhasm: fe AA */
/* qhasm: fe XX */
/* qhasm: fe YY */
/* qhasm: fe B */
/* qhasm: fe X3 */
/* qhasm: fe Y3 */
/* qhasm: fe Z3 */
/* qhasm: fe T3 */
/* qhasm: XX=X1^2 */
/* asm 1: fe_sq(>XX=fe#1,<X1=fe#11); */
/* asm 2: fe_sq(>XX=r->X,<X1=p->X); */
fe_sq(r->X,p->X);
/* qhasm: YY=Y1^2 */
/* asm 1: fe_sq(>YY=fe#3,<Y1=fe#12); */
/* asm 2: fe_sq(>YY=r->Z,<Y1=p->Y); */
fe_sq(r->Z,p->Y);
/* qhasm: B=2*Z1^2 */
/* asm 1: fe_sq2(>B=fe#4,<Z1=fe#13); */
/* asm 2: fe_sq2(>B=r->T,<Z1=p->Z); */
fe_sq2(r->T,p->Z);
/* qhasm: A=X1+Y1 */
/* asm 1: fe_add(>A=fe#2,<X1=fe#11,<Y1=fe#12); */
/* asm 2: fe_add(>A=r->Y,<X1=p->X,<Y1=p->Y); */
fe_add(r->Y,p->X,p->Y);
/* qhasm: AA=A^2 */
/* asm 1: fe_sq(>AA=fe#5,<A=fe#2); */
/* asm 2: fe_sq(>AA=t0,<A=r->Y); */
fe_sq(t0,r->Y);
/* qhasm: Y3=YY+XX */
/* asm 1: fe_add(>Y3=fe#2,<YY=fe#3,<XX=fe#1); */
/* asm 2: fe_add(>Y3=r->Y,<YY=r->Z,<XX=r->X); */
fe_add(r->Y,r->Z,r->X);
/* qhasm: Z3=YY-XX */
/* asm 1: fe_sub(>Z3=fe#3,<YY=fe#3,<XX=fe#1); */
/* asm 2: fe_sub(>Z3=r->Z,<YY=r->Z,<XX=r->X); */
fe_sub(r->Z,r->Z,r->X);
/* qhasm: X3=AA-Y3 */
/* asm 1: fe_sub(>X3=fe#1,<AA=fe#5,<Y3=fe#2); */
/* asm 2: fe_sub(>X3=r->X,<AA=t0,<Y3=r->Y); */
fe_sub(r->X,t0,r->Y);
/* qhasm: T3=B-Z3 */
/* asm 1: fe_sub(>T3=fe#4,<B=fe#4,<Z3=fe#3); */
/* asm 2: fe_sub(>T3=r->T,<B=r->T,<Z3=r->Z); */
fe_sub(r->T,r->T,r->Z);
/* qhasm: return */

View File

@ -0,0 +1,41 @@
:name:fe:r->X:r->Y:r->Z:r->T:t0:t1:t2:t3:t4:t5:p->X:p->Y:p->Z:
fe r:var/r=fe:
enter f:enter/f:>X1=fe#11:>Y1=fe#12:>Z1=fe#13:
return:nofallthrough:<X3=fe#1:<Y3=fe#2:<Z3=fe#3:<T3=fe#4:leave:
h=f+g:<f=fe:<g=fe:>h=fe:asm/fe_add(>h,<f,<g);:
h=f-g:<f=fe:<g=fe:>h=fe:asm/fe_sub(>h,<f,<g);:
h=f*g:<f=fe:<g=fe:>h=fe:asm/fe_mul(>h,<f,<g);:
h=f^2:<f=fe:>h=fe:asm/fe_sq(>h,<f);:
h=2*f^2:<f=fe:>h=fe:asm/fe_sq2(>h,<f);:
h=2*g:<g=fe:>h=fe:asm/fe_add(>h,<g,<g);:
:
enter ge_p2_dbl
fe X1
fe Y1
fe Z1
fe A
fe AA
fe XX
fe YY
fe B
fe X3
fe Y3
fe Z3
fe T3
XX=X1^2
YY=Y1^2
B=2*Z1^2
A=X1+Y1
AA=A^2
Y3=YY+XX
Z3=YY-XX
X3=AA-Y3
T3=B-Z3
return

View File

@ -0,0 +1,9 @@
#include "ge.h"
void ge_p3_0(ge_p3 *h)
{
fe_0(h->X);
fe_1(h->Y);
fe_1(h->Z);
fe_0(h->T);
}

View File

@ -0,0 +1,12 @@
#include "ge.h"
/*
r = 2 * p
*/
void ge_p3_dbl(ge_p1p1 *r,const ge_p3 *p)
{
ge_p2 q;
ge_p3_to_p2(&q,p);
ge_p2_dbl(r,&q);
}

View File

@ -0,0 +1,17 @@
#include "ge.h"
/*
r = p
*/
static const fe d2 = {
#include "d2.h"
} ;
extern void ge_p3_to_cached(ge_cached *r,const ge_p3 *p)
{
fe_add(r->YplusX,p->Y,p->X);
fe_sub(r->YminusX,p->Y,p->X);
fe_copy(r->Z,p->Z);
fe_mul(r->T2d,p->T,d2);
}

View File

@ -0,0 +1,12 @@
#include "ge.h"
/*
r = p
*/
extern void ge_p3_to_p2(ge_p2 *r,const ge_p3 *p)
{
fe_copy(r->X,p->X);
fe_copy(r->Y,p->Y);
fe_copy(r->Z,p->Z);
}

View File

@ -0,0 +1,14 @@
#include "ge.h"
void ge_p3_tobytes(unsigned char *s,const ge_p3 *h)
{
fe recip;
fe x;
fe y;
fe_invert(recip,h->Z);
fe_mul(x,h->X,recip);
fe_mul(y,h->Y,recip);
fe_tobytes(s,y);
s[31] ^= fe_isnegative(x) << 7;
}

View File

@ -0,0 +1,8 @@
#include "ge.h"
void ge_precomp_0(ge_precomp *h)
{
fe_1(h->yplusx);
fe_1(h->yminusx);
fe_0(h->xy2d);
}

View File

@ -0,0 +1,105 @@
#include "ge.h"
#include "crypto_uint32.h"
static unsigned char equal(signed char b,signed char c)
{
unsigned char ub = b;
unsigned char uc = c;
unsigned char x = ub ^ uc; /* 0: yes; 1..255: no */
crypto_uint32 y = x; /* 0: yes; 1..255: no */
y -= 1; /* 4294967295: yes; 0..254: no */
y >>= 31; /* 1: yes; 0: no */
return y;
}
static unsigned char negative(signed char b)
{
uint64_t x = b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */
x >>= 63; /* 1: yes; 0: no */
return x;
}
static void cmov(ge_precomp *t,ge_precomp *u,unsigned char b)
{
fe_cmov(t->yplusx,u->yplusx,b);
fe_cmov(t->yminusx,u->yminusx,b);
fe_cmov(t->xy2d,u->xy2d,b);
}
/* base[i][j] = (j+1)*256^i*B */
static ge_precomp base[32][8] = {
#include "base.h"
} ;
static void select(ge_precomp *t,int pos,signed char b)
{
ge_precomp minust;
unsigned char bnegative = negative(b);
unsigned char babs = b - (((-bnegative) & b) << 1);
ge_precomp_0(t);
cmov(t,&base[pos][0],equal(babs,1));
cmov(t,&base[pos][1],equal(babs,2));
cmov(t,&base[pos][2],equal(babs,3));
cmov(t,&base[pos][3],equal(babs,4));
cmov(t,&base[pos][4],equal(babs,5));
cmov(t,&base[pos][5],equal(babs,6));
cmov(t,&base[pos][6],equal(babs,7));
cmov(t,&base[pos][7],equal(babs,8));
fe_copy(minust.yplusx,t->yminusx);
fe_copy(minust.yminusx,t->yplusx);
fe_neg(minust.xy2d,t->xy2d);
cmov(t,&minust,bnegative);
}
/*
h = a * B
where a = a[0]+256*a[1]+...+256^31 a[31]
B is the Ed25519 base point (x,4/5) with x positive.
Preconditions:
a[31] <= 127
*/
void ge_scalarmult_base(ge_p3 *h,const unsigned char *a)
{
signed char e[64];
signed char carry;
ge_p1p1 r;
ge_p2 s;
ge_precomp t;
int i;
for (i = 0;i < 32;++i) {
e[2 * i + 0] = (a[i] >> 0) & 15;
e[2 * i + 1] = (a[i] >> 4) & 15;
}
/* each e[i] is between 0 and 15 */
/* e[63] is between 0 and 7 */
carry = 0;
for (i = 0;i < 63;++i) {
e[i] += carry;
carry = e[i] + 8;
carry >>= 4;
e[i] -= carry << 4;
}
e[63] += carry;
/* each e[i] is between -8 and 8 */
ge_p3_0(h);
for (i = 1;i < 64;i += 2) {
select(&t,i / 2,e[i]);
ge_madd(&r,h,&t); ge_p1p1_to_p3(h,&r);
}
ge_p3_dbl(&r,h); ge_p1p1_to_p2(&s,&r);
ge_p2_dbl(&r,&s); ge_p1p1_to_p2(&s,&r);
ge_p2_dbl(&r,&s); ge_p1p1_to_p2(&s,&r);
ge_p2_dbl(&r,&s); ge_p1p1_to_p3(h,&r);
for (i = 0;i < 64;i += 2) {
select(&t,i / 2,e[i]);
ge_madd(&r,h,&t); ge_p1p1_to_p3(h,&r);
}
}

View File

@ -0,0 +1,11 @@
#include "ge.h"
/*
r = p - q
*/
void ge_sub(ge_p1p1 *r,const ge_p3 *p,const ge_cached *q)
{
fe t0;
#include "ge_sub.h"
}

View File

@ -0,0 +1,97 @@
/* qhasm: enter ge_sub */
/* qhasm: fe X1 */
/* qhasm: fe Y1 */
/* qhasm: fe Z1 */
/* qhasm: fe Z2 */
/* qhasm: fe T1 */
/* qhasm: fe ZZ */
/* qhasm: fe YpX2 */
/* qhasm: fe YmX2 */
/* qhasm: fe T2d2 */
/* qhasm: fe X3 */
/* qhasm: fe Y3 */
/* qhasm: fe Z3 */
/* qhasm: fe T3 */
/* qhasm: fe YpX1 */
/* qhasm: fe YmX1 */
/* qhasm: fe A */
/* qhasm: fe B */
/* qhasm: fe C */
/* qhasm: fe D */
/* qhasm: YpX1 = Y1+X1 */
/* asm 1: fe_add(>YpX1=fe#1,<Y1=fe#12,<X1=fe#11); */
/* asm 2: fe_add(>YpX1=r->X,<Y1=p->Y,<X1=p->X); */
fe_add(r->X,p->Y,p->X);
/* qhasm: YmX1 = Y1-X1 */
/* asm 1: fe_sub(>YmX1=fe#2,<Y1=fe#12,<X1=fe#11); */
/* asm 2: fe_sub(>YmX1=r->Y,<Y1=p->Y,<X1=p->X); */
fe_sub(r->Y,p->Y,p->X);
/* qhasm: A = YpX1*YmX2 */
/* asm 1: fe_mul(>A=fe#3,<YpX1=fe#1,<YmX2=fe#16); */
/* asm 2: fe_mul(>A=r->Z,<YpX1=r->X,<YmX2=q->YminusX); */
fe_mul(r->Z,r->X,q->YminusX);
/* qhasm: B = YmX1*YpX2 */
/* asm 1: fe_mul(>B=fe#2,<YmX1=fe#2,<YpX2=fe#15); */
/* asm 2: fe_mul(>B=r->Y,<YmX1=r->Y,<YpX2=q->YplusX); */
fe_mul(r->Y,r->Y,q->YplusX);
/* qhasm: C = T2d2*T1 */
/* asm 1: fe_mul(>C=fe#4,<T2d2=fe#18,<T1=fe#14); */
/* asm 2: fe_mul(>C=r->T,<T2d2=q->T2d,<T1=p->T); */
fe_mul(r->T,q->T2d,p->T);
/* qhasm: ZZ = Z1*Z2 */
/* asm 1: fe_mul(>ZZ=fe#1,<Z1=fe#13,<Z2=fe#17); */
/* asm 2: fe_mul(>ZZ=r->X,<Z1=p->Z,<Z2=q->Z); */
fe_mul(r->X,p->Z,q->Z);
/* qhasm: D = 2*ZZ */
/* asm 1: fe_add(>D=fe#5,<ZZ=fe#1,<ZZ=fe#1); */
/* asm 2: fe_add(>D=t0,<ZZ=r->X,<ZZ=r->X); */
fe_add(t0,r->X,r->X);
/* qhasm: X3 = A-B */
/* asm 1: fe_sub(>X3=fe#1,<A=fe#3,<B=fe#2); */
/* asm 2: fe_sub(>X3=r->X,<A=r->Z,<B=r->Y); */
fe_sub(r->X,r->Z,r->Y);
/* qhasm: Y3 = A+B */
/* asm 1: fe_add(>Y3=fe#2,<A=fe#3,<B=fe#2); */
/* asm 2: fe_add(>Y3=r->Y,<A=r->Z,<B=r->Y); */
fe_add(r->Y,r->Z,r->Y);
/* qhasm: Z3 = D-C */
/* asm 1: fe_sub(>Z3=fe#3,<D=fe#5,<C=fe#4); */
/* asm 2: fe_sub(>Z3=r->Z,<D=t0,<C=r->T); */
fe_sub(r->Z,t0,r->T);
/* qhasm: T3 = D+C */
/* asm 1: fe_add(>T3=fe#4,<D=fe#5,<C=fe#4); */
/* asm 2: fe_add(>T3=r->T,<D=t0,<C=r->T); */
fe_add(r->T,t0,r->T);
/* qhasm: return */

View File

@ -0,0 +1,49 @@
:name:fe:r->X:r->Y:r->Z:r->T:t0:t1:t2:t3:t4:t5:p->X:p->Y:p->Z:p->T:q->YplusX:q->YminusX:q->Z:q->T2d:
fe r:var/r=fe:
enter f:enter/f:>X1=fe#11:>Y1=fe#12:>Z1=fe#13:>T1=fe#14:>YpX2=fe#15:>YmX2=fe#16:>Z2=fe#17:>T2d2=fe#18:
return:nofallthrough:<X3=fe#1:<Y3=fe#2:<Z3=fe#3:<T3=fe#4:leave:
h=f+g:<f=fe:<g=fe:>h=fe:asm/fe_add(>h,<f,<g);:
h=f-g:<f=fe:<g=fe:>h=fe:asm/fe_sub(>h,<f,<g);:
h=f*g:<f=fe:<g=fe:>h=fe:asm/fe_mul(>h,<f,<g);:
h=f^2:<f=fe:>h=fe:asm/fe_sq(>h,<f);:
h=2*g:<g=fe:>h=fe:asm/fe_add(>h,<g,<g);:
:
enter ge_sub
fe X1
fe Y1
fe Z1
fe Z2
fe T1
fe ZZ
fe YpX2
fe YmX2
fe T2d2
fe X3
fe Y3
fe Z3
fe T3
fe YpX1
fe YmX1
fe A
fe B
fe C
fe D
YpX1 = Y1+X1
YmX1 = Y1-X1
A = YpX1*YmX2
B = YmX1*YpX2
C = T2d2*T1
ZZ = Z1*Z2
D = 2*ZZ
X3 = A-B
Y3 = A+B
Z3 = D-C
T3 = D+C
return

View File

@ -0,0 +1,14 @@
#include "ge.h"
void ge_tobytes(unsigned char *s,const ge_p2 *h)
{
fe recip;
fe x;
fe y;
fe_invert(recip,h->Z);
fe_mul(x,h->X,recip);
fe_mul(y,h->Y,recip);
fe_tobytes(s,y);
s[31] ^= fe_isnegative(x) << 7;
}

View File

@ -0,0 +1,20 @@
#include <string.h>
#include "crypto_sign.h"
#include "crypto_hash_sha512.h"
#include "ge.h"
int crypto_sign_pubkey(unsigned char*pk, const unsigned char* sk)
{
unsigned char az[64];
ge_p3 A;
crypto_hash_sha512(az,sk,32);
az[0] &= 248;
az[31] &= 63;
az[31] |= 64;
ge_scalarmult_base(&A,az);
ge_p3_tobytes(pk,&A);
return 0;
}

View File

@ -0,0 +1,39 @@
#include <string.h>
#include "crypto_sign.h"
#include "crypto_hash_sha512.h"
#include "crypto_verify_32.h"
#include "ge.h"
#include "sc.h"
int crypto_sign_open(
const unsigned char* sig,
const unsigned char* m, size_t mlen,
const unsigned char* pk
)
{
unsigned char pkcopy[32];
unsigned char rcopy[32];
unsigned char scopy[32];
unsigned char h[64];
unsigned char rcheck[32];
ge_p3 A;
ge_p2 R;
if (sig[63] & 224) goto badsig;
if (ge_frombytes_negate_vartime(&A,pk) != 0) goto badsig;
memmove(pkcopy,pk,32);
memmove(rcopy, sig, 32);
memmove(scopy, sig + 32,32);
crypto_hash_sha512_3(h, rcopy, 32, pkcopy, 32, m, mlen);
sc_reduce(h);
ge_double_scalarmult_vartime(&R,h,&A,scopy);
ge_tobytes(rcheck,&R);
if (crypto_verify_32(rcheck,rcopy) == 0)
return 0;
badsig:
return -1;
}

View File

@ -0,0 +1,160 @@
/* qhasm: fe z1 */
/* qhasm: fe z2 */
/* qhasm: fe z8 */
/* qhasm: fe z9 */
/* qhasm: fe z11 */
/* qhasm: fe z22 */
/* qhasm: fe z_5_0 */
/* qhasm: fe z_10_5 */
/* qhasm: fe z_10_0 */
/* qhasm: fe z_20_10 */
/* qhasm: fe z_20_0 */
/* qhasm: fe z_40_20 */
/* qhasm: fe z_40_0 */
/* qhasm: fe z_50_10 */
/* qhasm: fe z_50_0 */
/* qhasm: fe z_100_50 */
/* qhasm: fe z_100_0 */
/* qhasm: fe z_200_100 */
/* qhasm: fe z_200_0 */
/* qhasm: fe z_250_50 */
/* qhasm: fe z_250_0 */
/* qhasm: fe z_252_2 */
/* qhasm: fe z_252_3 */
/* qhasm: enter pow22523 */
/* qhasm: z2 = z1^2^1 */
/* asm 1: fe_sq(>z2=fe#1,<z1=fe#11); for (i = 1;i < 1;++i) fe_sq(>z2=fe#1,>z2=fe#1); */
/* asm 2: fe_sq(>z2=t0,<z1=z); for (i = 1;i < 1;++i) fe_sq(>z2=t0,>z2=t0); */
fe_sq(t0,z); for (i = 1;i < 1;++i) fe_sq(t0,t0);
/* qhasm: z8 = z2^2^2 */
/* asm 1: fe_sq(>z8=fe#2,<z2=fe#1); for (i = 1;i < 2;++i) fe_sq(>z8=fe#2,>z8=fe#2); */
/* asm 2: fe_sq(>z8=t1,<z2=t0); for (i = 1;i < 2;++i) fe_sq(>z8=t1,>z8=t1); */
fe_sq(t1,t0); for (i = 1;i < 2;++i) fe_sq(t1,t1);
/* qhasm: z9 = z1*z8 */
/* asm 1: fe_mul(>z9=fe#2,<z1=fe#11,<z8=fe#2); */
/* asm 2: fe_mul(>z9=t1,<z1=z,<z8=t1); */
fe_mul(t1,z,t1);
/* qhasm: z11 = z2*z9 */
/* asm 1: fe_mul(>z11=fe#1,<z2=fe#1,<z9=fe#2); */
/* asm 2: fe_mul(>z11=t0,<z2=t0,<z9=t1); */
fe_mul(t0,t0,t1);
/* qhasm: z22 = z11^2^1 */
/* asm 1: fe_sq(>z22=fe#1,<z11=fe#1); for (i = 1;i < 1;++i) fe_sq(>z22=fe#1,>z22=fe#1); */
/* asm 2: fe_sq(>z22=t0,<z11=t0); for (i = 1;i < 1;++i) fe_sq(>z22=t0,>z22=t0); */
fe_sq(t0,t0); for (i = 1;i < 1;++i) fe_sq(t0,t0);
/* qhasm: z_5_0 = z9*z22 */
/* asm 1: fe_mul(>z_5_0=fe#1,<z9=fe#2,<z22=fe#1); */
/* asm 2: fe_mul(>z_5_0=t0,<z9=t1,<z22=t0); */
fe_mul(t0,t1,t0);
/* qhasm: z_10_5 = z_5_0^2^5 */
/* asm 1: fe_sq(>z_10_5=fe#2,<z_5_0=fe#1); for (i = 1;i < 5;++i) fe_sq(>z_10_5=fe#2,>z_10_5=fe#2); */
/* asm 2: fe_sq(>z_10_5=t1,<z_5_0=t0); for (i = 1;i < 5;++i) fe_sq(>z_10_5=t1,>z_10_5=t1); */
fe_sq(t1,t0); for (i = 1;i < 5;++i) fe_sq(t1,t1);
/* qhasm: z_10_0 = z_10_5*z_5_0 */
/* asm 1: fe_mul(>z_10_0=fe#1,<z_10_5=fe#2,<z_5_0=fe#1); */
/* asm 2: fe_mul(>z_10_0=t0,<z_10_5=t1,<z_5_0=t0); */
fe_mul(t0,t1,t0);
/* qhasm: z_20_10 = z_10_0^2^10 */
/* asm 1: fe_sq(>z_20_10=fe#2,<z_10_0=fe#1); for (i = 1;i < 10;++i) fe_sq(>z_20_10=fe#2,>z_20_10=fe#2); */
/* asm 2: fe_sq(>z_20_10=t1,<z_10_0=t0); for (i = 1;i < 10;++i) fe_sq(>z_20_10=t1,>z_20_10=t1); */
fe_sq(t1,t0); for (i = 1;i < 10;++i) fe_sq(t1,t1);
/* qhasm: z_20_0 = z_20_10*z_10_0 */
/* asm 1: fe_mul(>z_20_0=fe#2,<z_20_10=fe#2,<z_10_0=fe#1); */
/* asm 2: fe_mul(>z_20_0=t1,<z_20_10=t1,<z_10_0=t0); */
fe_mul(t1,t1,t0);
/* qhasm: z_40_20 = z_20_0^2^20 */
/* asm 1: fe_sq(>z_40_20=fe#3,<z_20_0=fe#2); for (i = 1;i < 20;++i) fe_sq(>z_40_20=fe#3,>z_40_20=fe#3); */
/* asm 2: fe_sq(>z_40_20=t2,<z_20_0=t1); for (i = 1;i < 20;++i) fe_sq(>z_40_20=t2,>z_40_20=t2); */
fe_sq(t2,t1); for (i = 1;i < 20;++i) fe_sq(t2,t2);
/* qhasm: z_40_0 = z_40_20*z_20_0 */
/* asm 1: fe_mul(>z_40_0=fe#2,<z_40_20=fe#3,<z_20_0=fe#2); */
/* asm 2: fe_mul(>z_40_0=t1,<z_40_20=t2,<z_20_0=t1); */
fe_mul(t1,t2,t1);
/* qhasm: z_50_10 = z_40_0^2^10 */
/* asm 1: fe_sq(>z_50_10=fe#2,<z_40_0=fe#2); for (i = 1;i < 10;++i) fe_sq(>z_50_10=fe#2,>z_50_10=fe#2); */
/* asm 2: fe_sq(>z_50_10=t1,<z_40_0=t1); for (i = 1;i < 10;++i) fe_sq(>z_50_10=t1,>z_50_10=t1); */
fe_sq(t1,t1); for (i = 1;i < 10;++i) fe_sq(t1,t1);
/* qhasm: z_50_0 = z_50_10*z_10_0 */
/* asm 1: fe_mul(>z_50_0=fe#1,<z_50_10=fe#2,<z_10_0=fe#1); */
/* asm 2: fe_mul(>z_50_0=t0,<z_50_10=t1,<z_10_0=t0); */
fe_mul(t0,t1,t0);
/* qhasm: z_100_50 = z_50_0^2^50 */
/* asm 1: fe_sq(>z_100_50=fe#2,<z_50_0=fe#1); for (i = 1;i < 50;++i) fe_sq(>z_100_50=fe#2,>z_100_50=fe#2); */
/* asm 2: fe_sq(>z_100_50=t1,<z_50_0=t0); for (i = 1;i < 50;++i) fe_sq(>z_100_50=t1,>z_100_50=t1); */
fe_sq(t1,t0); for (i = 1;i < 50;++i) fe_sq(t1,t1);
/* qhasm: z_100_0 = z_100_50*z_50_0 */
/* asm 1: fe_mul(>z_100_0=fe#2,<z_100_50=fe#2,<z_50_0=fe#1); */
/* asm 2: fe_mul(>z_100_0=t1,<z_100_50=t1,<z_50_0=t0); */
fe_mul(t1,t1,t0);
/* qhasm: z_200_100 = z_100_0^2^100 */
/* asm 1: fe_sq(>z_200_100=fe#3,<z_100_0=fe#2); for (i = 1;i < 100;++i) fe_sq(>z_200_100=fe#3,>z_200_100=fe#3); */
/* asm 2: fe_sq(>z_200_100=t2,<z_100_0=t1); for (i = 1;i < 100;++i) fe_sq(>z_200_100=t2,>z_200_100=t2); */
fe_sq(t2,t1); for (i = 1;i < 100;++i) fe_sq(t2,t2);
/* qhasm: z_200_0 = z_200_100*z_100_0 */
/* asm 1: fe_mul(>z_200_0=fe#2,<z_200_100=fe#3,<z_100_0=fe#2); */
/* asm 2: fe_mul(>z_200_0=t1,<z_200_100=t2,<z_100_0=t1); */
fe_mul(t1,t2,t1);
/* qhasm: z_250_50 = z_200_0^2^50 */
/* asm 1: fe_sq(>z_250_50=fe#2,<z_200_0=fe#2); for (i = 1;i < 50;++i) fe_sq(>z_250_50=fe#2,>z_250_50=fe#2); */
/* asm 2: fe_sq(>z_250_50=t1,<z_200_0=t1); for (i = 1;i < 50;++i) fe_sq(>z_250_50=t1,>z_250_50=t1); */
fe_sq(t1,t1); for (i = 1;i < 50;++i) fe_sq(t1,t1);
/* qhasm: z_250_0 = z_250_50*z_50_0 */
/* asm 1: fe_mul(>z_250_0=fe#1,<z_250_50=fe#2,<z_50_0=fe#1); */
/* asm 2: fe_mul(>z_250_0=t0,<z_250_50=t1,<z_50_0=t0); */
fe_mul(t0,t1,t0);
/* qhasm: z_252_2 = z_250_0^2^2 */
/* asm 1: fe_sq(>z_252_2=fe#1,<z_250_0=fe#1); for (i = 1;i < 2;++i) fe_sq(>z_252_2=fe#1,>z_252_2=fe#1); */
/* asm 2: fe_sq(>z_252_2=t0,<z_250_0=t0); for (i = 1;i < 2;++i) fe_sq(>z_252_2=t0,>z_252_2=t0); */
fe_sq(t0,t0); for (i = 1;i < 2;++i) fe_sq(t0,t0);
/* qhasm: z_252_3 = z_252_2*z1 */
/* asm 1: fe_mul(>z_252_3=fe#12,<z_252_2=fe#1,<z1=fe#11); */
/* asm 2: fe_mul(>z_252_3=out,<z_252_2=t0,<z1=z); */
fe_mul(out,t0,z);
/* qhasm: return */

View File

@ -0,0 +1,61 @@
:name:fe:t0:t1:t2:t3:t4:t5:t6:t7:t8:t9:z:out:
fe r:var/r=fe:
enter f:enter/f:>z1=fe#11:
return:nofallthrough:<z_252_3=fe#12:leave:
h=f*g:<f=fe:<g=fe:>h=fe:asm/fe_mul(>h,<f,<g);:
h=f^2^k:<f=fe:>h=fe:#k:asm/fe_sq(>h,<f); for (i = 1;i !lt; #k;++i) fe_sq(>h,>h);:
:
fe z1
fe z2
fe z8
fe z9
fe z11
fe z22
fe z_5_0
fe z_10_5
fe z_10_0
fe z_20_10
fe z_20_0
fe z_40_20
fe z_40_0
fe z_50_10
fe z_50_0
fe z_100_50
fe z_100_0
fe z_200_100
fe z_200_0
fe z_250_50
fe z_250_0
fe z_252_2
fe z_252_3
enter pow22523
z2 = z1^2^1
z8 = z2^2^2
z9 = z1*z8
z11 = z2*z9
z22 = z11^2^1
z_5_0 = z9*z22
z_10_5 = z_5_0^2^5
z_10_0 = z_10_5*z_5_0
z_20_10 = z_10_0^2^10
z_20_0 = z_20_10*z_10_0
z_40_20 = z_20_0^2^20
z_40_0 = z_40_20*z_20_0
z_50_10 = z_40_0^2^10
z_50_0 = z_50_10*z_10_0
z_100_50 = z_50_0^2^50
z_100_0 = z_100_50*z_50_0
z_200_100 = z_100_0^2^100
z_200_0 = z_200_100*z_100_0
z_250_50 = z_200_0^2^50
z_250_0 = z_250_50*z_50_0
z_252_2 = z_250_0^2^2
z_252_3 = z_252_2*z1
return

View File

@ -0,0 +1,160 @@
/* qhasm: fe z1 */
/* qhasm: fe z2 */
/* qhasm: fe z8 */
/* qhasm: fe z9 */
/* qhasm: fe z11 */
/* qhasm: fe z22 */
/* qhasm: fe z_5_0 */
/* qhasm: fe z_10_5 */
/* qhasm: fe z_10_0 */
/* qhasm: fe z_20_10 */
/* qhasm: fe z_20_0 */
/* qhasm: fe z_40_20 */
/* qhasm: fe z_40_0 */
/* qhasm: fe z_50_10 */
/* qhasm: fe z_50_0 */
/* qhasm: fe z_100_50 */
/* qhasm: fe z_100_0 */
/* qhasm: fe z_200_100 */
/* qhasm: fe z_200_0 */
/* qhasm: fe z_250_50 */
/* qhasm: fe z_250_0 */
/* qhasm: fe z_255_5 */
/* qhasm: fe z_255_21 */
/* qhasm: enter pow225521 */
/* qhasm: z2 = z1^2^1 */
/* asm 1: fe_sq(>z2=fe#1,<z1=fe#11); for (i = 1;i < 1;++i) fe_sq(>z2=fe#1,>z2=fe#1); */
/* asm 2: fe_sq(>z2=t0,<z1=z); for (i = 1;i < 1;++i) fe_sq(>z2=t0,>z2=t0); */
fe_sq(t0,z); for (i = 1;i < 1;++i) fe_sq(t0,t0);
/* qhasm: z8 = z2^2^2 */
/* asm 1: fe_sq(>z8=fe#2,<z2=fe#1); for (i = 1;i < 2;++i) fe_sq(>z8=fe#2,>z8=fe#2); */
/* asm 2: fe_sq(>z8=t1,<z2=t0); for (i = 1;i < 2;++i) fe_sq(>z8=t1,>z8=t1); */
fe_sq(t1,t0); for (i = 1;i < 2;++i) fe_sq(t1,t1);
/* qhasm: z9 = z1*z8 */
/* asm 1: fe_mul(>z9=fe#2,<z1=fe#11,<z8=fe#2); */
/* asm 2: fe_mul(>z9=t1,<z1=z,<z8=t1); */
fe_mul(t1,z,t1);
/* qhasm: z11 = z2*z9 */
/* asm 1: fe_mul(>z11=fe#1,<z2=fe#1,<z9=fe#2); */
/* asm 2: fe_mul(>z11=t0,<z2=t0,<z9=t1); */
fe_mul(t0,t0,t1);
/* qhasm: z22 = z11^2^1 */
/* asm 1: fe_sq(>z22=fe#3,<z11=fe#1); for (i = 1;i < 1;++i) fe_sq(>z22=fe#3,>z22=fe#3); */
/* asm 2: fe_sq(>z22=t2,<z11=t0); for (i = 1;i < 1;++i) fe_sq(>z22=t2,>z22=t2); */
fe_sq(t2,t0); for (i = 1;i < 1;++i) fe_sq(t2,t2);
/* qhasm: z_5_0 = z9*z22 */
/* asm 1: fe_mul(>z_5_0=fe#2,<z9=fe#2,<z22=fe#3); */
/* asm 2: fe_mul(>z_5_0=t1,<z9=t1,<z22=t2); */
fe_mul(t1,t1,t2);
/* qhasm: z_10_5 = z_5_0^2^5 */
/* asm 1: fe_sq(>z_10_5=fe#3,<z_5_0=fe#2); for (i = 1;i < 5;++i) fe_sq(>z_10_5=fe#3,>z_10_5=fe#3); */
/* asm 2: fe_sq(>z_10_5=t2,<z_5_0=t1); for (i = 1;i < 5;++i) fe_sq(>z_10_5=t2,>z_10_5=t2); */
fe_sq(t2,t1); for (i = 1;i < 5;++i) fe_sq(t2,t2);
/* qhasm: z_10_0 = z_10_5*z_5_0 */
/* asm 1: fe_mul(>z_10_0=fe#2,<z_10_5=fe#3,<z_5_0=fe#2); */
/* asm 2: fe_mul(>z_10_0=t1,<z_10_5=t2,<z_5_0=t1); */
fe_mul(t1,t2,t1);
/* qhasm: z_20_10 = z_10_0^2^10 */
/* asm 1: fe_sq(>z_20_10=fe#3,<z_10_0=fe#2); for (i = 1;i < 10;++i) fe_sq(>z_20_10=fe#3,>z_20_10=fe#3); */
/* asm 2: fe_sq(>z_20_10=t2,<z_10_0=t1); for (i = 1;i < 10;++i) fe_sq(>z_20_10=t2,>z_20_10=t2); */
fe_sq(t2,t1); for (i = 1;i < 10;++i) fe_sq(t2,t2);
/* qhasm: z_20_0 = z_20_10*z_10_0 */
/* asm 1: fe_mul(>z_20_0=fe#3,<z_20_10=fe#3,<z_10_0=fe#2); */
/* asm 2: fe_mul(>z_20_0=t2,<z_20_10=t2,<z_10_0=t1); */
fe_mul(t2,t2,t1);
/* qhasm: z_40_20 = z_20_0^2^20 */
/* asm 1: fe_sq(>z_40_20=fe#4,<z_20_0=fe#3); for (i = 1;i < 20;++i) fe_sq(>z_40_20=fe#4,>z_40_20=fe#4); */
/* asm 2: fe_sq(>z_40_20=t3,<z_20_0=t2); for (i = 1;i < 20;++i) fe_sq(>z_40_20=t3,>z_40_20=t3); */
fe_sq(t3,t2); for (i = 1;i < 20;++i) fe_sq(t3,t3);
/* qhasm: z_40_0 = z_40_20*z_20_0 */
/* asm 1: fe_mul(>z_40_0=fe#3,<z_40_20=fe#4,<z_20_0=fe#3); */
/* asm 2: fe_mul(>z_40_0=t2,<z_40_20=t3,<z_20_0=t2); */
fe_mul(t2,t3,t2);
/* qhasm: z_50_10 = z_40_0^2^10 */
/* asm 1: fe_sq(>z_50_10=fe#3,<z_40_0=fe#3); for (i = 1;i < 10;++i) fe_sq(>z_50_10=fe#3,>z_50_10=fe#3); */
/* asm 2: fe_sq(>z_50_10=t2,<z_40_0=t2); for (i = 1;i < 10;++i) fe_sq(>z_50_10=t2,>z_50_10=t2); */
fe_sq(t2,t2); for (i = 1;i < 10;++i) fe_sq(t2,t2);
/* qhasm: z_50_0 = z_50_10*z_10_0 */
/* asm 1: fe_mul(>z_50_0=fe#2,<z_50_10=fe#3,<z_10_0=fe#2); */
/* asm 2: fe_mul(>z_50_0=t1,<z_50_10=t2,<z_10_0=t1); */
fe_mul(t1,t2,t1);
/* qhasm: z_100_50 = z_50_0^2^50 */
/* asm 1: fe_sq(>z_100_50=fe#3,<z_50_0=fe#2); for (i = 1;i < 50;++i) fe_sq(>z_100_50=fe#3,>z_100_50=fe#3); */
/* asm 2: fe_sq(>z_100_50=t2,<z_50_0=t1); for (i = 1;i < 50;++i) fe_sq(>z_100_50=t2,>z_100_50=t2); */
fe_sq(t2,t1); for (i = 1;i < 50;++i) fe_sq(t2,t2);
/* qhasm: z_100_0 = z_100_50*z_50_0 */
/* asm 1: fe_mul(>z_100_0=fe#3,<z_100_50=fe#3,<z_50_0=fe#2); */
/* asm 2: fe_mul(>z_100_0=t2,<z_100_50=t2,<z_50_0=t1); */
fe_mul(t2,t2,t1);
/* qhasm: z_200_100 = z_100_0^2^100 */
/* asm 1: fe_sq(>z_200_100=fe#4,<z_100_0=fe#3); for (i = 1;i < 100;++i) fe_sq(>z_200_100=fe#4,>z_200_100=fe#4); */
/* asm 2: fe_sq(>z_200_100=t3,<z_100_0=t2); for (i = 1;i < 100;++i) fe_sq(>z_200_100=t3,>z_200_100=t3); */
fe_sq(t3,t2); for (i = 1;i < 100;++i) fe_sq(t3,t3);
/* qhasm: z_200_0 = z_200_100*z_100_0 */
/* asm 1: fe_mul(>z_200_0=fe#3,<z_200_100=fe#4,<z_100_0=fe#3); */
/* asm 2: fe_mul(>z_200_0=t2,<z_200_100=t3,<z_100_0=t2); */
fe_mul(t2,t3,t2);
/* qhasm: z_250_50 = z_200_0^2^50 */
/* asm 1: fe_sq(>z_250_50=fe#3,<z_200_0=fe#3); for (i = 1;i < 50;++i) fe_sq(>z_250_50=fe#3,>z_250_50=fe#3); */
/* asm 2: fe_sq(>z_250_50=t2,<z_200_0=t2); for (i = 1;i < 50;++i) fe_sq(>z_250_50=t2,>z_250_50=t2); */
fe_sq(t2,t2); for (i = 1;i < 50;++i) fe_sq(t2,t2);
/* qhasm: z_250_0 = z_250_50*z_50_0 */
/* asm 1: fe_mul(>z_250_0=fe#2,<z_250_50=fe#3,<z_50_0=fe#2); */
/* asm 2: fe_mul(>z_250_0=t1,<z_250_50=t2,<z_50_0=t1); */
fe_mul(t1,t2,t1);
/* qhasm: z_255_5 = z_250_0^2^5 */
/* asm 1: fe_sq(>z_255_5=fe#2,<z_250_0=fe#2); for (i = 1;i < 5;++i) fe_sq(>z_255_5=fe#2,>z_255_5=fe#2); */
/* asm 2: fe_sq(>z_255_5=t1,<z_250_0=t1); for (i = 1;i < 5;++i) fe_sq(>z_255_5=t1,>z_255_5=t1); */
fe_sq(t1,t1); for (i = 1;i < 5;++i) fe_sq(t1,t1);
/* qhasm: z_255_21 = z_255_5*z11 */
/* asm 1: fe_mul(>z_255_21=fe#12,<z_255_5=fe#2,<z11=fe#1); */
/* asm 2: fe_mul(>z_255_21=out,<z_255_5=t1,<z11=t0); */
fe_mul(out,t1,t0);
/* qhasm: return */

View File

@ -0,0 +1,61 @@
:name:fe:t0:t1:t2:t3:t4:t5:t6:t7:t8:t9:z:out:
fe r:var/r=fe:
enter f:enter/f:>z1=fe#11:
return:nofallthrough:<z_255_21=fe#12:leave:
h=f*g:<f=fe:<g=fe:>h=fe:asm/fe_mul(>h,<f,<g);:
h=f^2^k:<f=fe:>h=fe:#k:asm/fe_sq(>h,<f); for (i = 1;i !lt; #k;++i) fe_sq(>h,>h);:
:
fe z1
fe z2
fe z8
fe z9
fe z11
fe z22
fe z_5_0
fe z_10_5
fe z_10_0
fe z_20_10
fe z_20_0
fe z_40_20
fe z_40_0
fe z_50_10
fe z_50_0
fe z_100_50
fe z_100_0
fe z_200_100
fe z_200_0
fe z_250_50
fe z_250_0
fe z_255_5
fe z_255_21
enter pow225521
z2 = z1^2^1
z8 = z2^2^2
z9 = z1*z8
z11 = z2*z9
z22 = z11^2^1
z_5_0 = z9*z22
z_10_5 = z_5_0^2^5
z_10_0 = z_10_5*z_5_0
z_20_10 = z_10_0^2^10
z_20_0 = z_20_10*z_10_0
z_40_20 = z_20_0^2^20
z_40_0 = z_40_20*z_20_0
z_50_10 = z_40_0^2^10
z_50_0 = z_50_10*z_10_0
z_100_50 = z_50_0^2^50
z_100_0 = z_100_50*z_50_0
z_200_100 = z_100_0^2^100
z_200_0 = z_200_100*z_100_0
z_250_50 = z_200_0^2^50
z_250_0 = z_250_50*z_50_0
z_255_5 = z_250_0^2^5
z_255_21 = z_255_5*z11
return

4
core/crypto/ed25519/q2h.sh Executable file
View File

@ -0,0 +1,4 @@
#!/bin/sh
sed 's/^#.*//' \
| qhasm-generic \
| sed 's_//\(.*\)$_/*\1 */_'

15
core/crypto/ed25519/sc.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef SC_H
#define SC_H
/*
The set of scalars is \Z/l
where l = 2^252 + 27742317777372353535851937790883648493.
*/
#define sc_reduce crypto_sign_ed25519_ref10_sc_reduce
#define sc_muladd crypto_sign_ed25519_ref10_sc_muladd
extern void sc_reduce(unsigned char *);
extern void sc_muladd(unsigned char *,const unsigned char *,const unsigned char *,const unsigned char *);
#endif

View File

@ -0,0 +1,368 @@
#include "sc.h"
#include "crypto_int64.h"
#include "crypto_uint32.h"
#include "crypto_uint64.h"
static crypto_uint64 load_3(const unsigned char *in)
{
crypto_uint64 result;
result = (crypto_uint64) in[0];
result |= ((crypto_uint64) in[1]) << 8;
result |= ((crypto_uint64) in[2]) << 16;
return result;
}
static crypto_uint64 load_4(const unsigned char *in)
{
crypto_uint64 result;
result = (crypto_uint64) in[0];
result |= ((crypto_uint64) in[1]) << 8;
result |= ((crypto_uint64) in[2]) << 16;
result |= ((crypto_uint64) in[3]) << 24;
return result;
}
/*
Input:
a[0]+256*a[1]+...+256^31*a[31] = a
b[0]+256*b[1]+...+256^31*b[31] = b
c[0]+256*c[1]+...+256^31*c[31] = c
Output:
s[0]+256*s[1]+...+256^31*s[31] = (ab+c) mod l
where l = 2^252 + 27742317777372353535851937790883648493.
*/
void sc_muladd(unsigned char *s,const unsigned char *a,const unsigned char *b,const unsigned char *c)
{
crypto_int64 a0 = 2097151 & load_3(a);
crypto_int64 a1 = 2097151 & (load_4(a + 2) >> 5);
crypto_int64 a2 = 2097151 & (load_3(a + 5) >> 2);
crypto_int64 a3 = 2097151 & (load_4(a + 7) >> 7);
crypto_int64 a4 = 2097151 & (load_4(a + 10) >> 4);
crypto_int64 a5 = 2097151 & (load_3(a + 13) >> 1);
crypto_int64 a6 = 2097151 & (load_4(a + 15) >> 6);
crypto_int64 a7 = 2097151 & (load_3(a + 18) >> 3);
crypto_int64 a8 = 2097151 & load_3(a + 21);
crypto_int64 a9 = 2097151 & (load_4(a + 23) >> 5);
crypto_int64 a10 = 2097151 & (load_3(a + 26) >> 2);
crypto_int64 a11 = (load_4(a + 28) >> 7);
crypto_int64 b0 = 2097151 & load_3(b);
crypto_int64 b1 = 2097151 & (load_4(b + 2) >> 5);
crypto_int64 b2 = 2097151 & (load_3(b + 5) >> 2);
crypto_int64 b3 = 2097151 & (load_4(b + 7) >> 7);
crypto_int64 b4 = 2097151 & (load_4(b + 10) >> 4);
crypto_int64 b5 = 2097151 & (load_3(b + 13) >> 1);
crypto_int64 b6 = 2097151 & (load_4(b + 15) >> 6);
crypto_int64 b7 = 2097151 & (load_3(b + 18) >> 3);
crypto_int64 b8 = 2097151 & load_3(b + 21);
crypto_int64 b9 = 2097151 & (load_4(b + 23) >> 5);
crypto_int64 b10 = 2097151 & (load_3(b + 26) >> 2);
crypto_int64 b11 = (load_4(b + 28) >> 7);
crypto_int64 c0 = 2097151 & load_3(c);
crypto_int64 c1 = 2097151 & (load_4(c + 2) >> 5);
crypto_int64 c2 = 2097151 & (load_3(c + 5) >> 2);
crypto_int64 c3 = 2097151 & (load_4(c + 7) >> 7);
crypto_int64 c4 = 2097151 & (load_4(c + 10) >> 4);
crypto_int64 c5 = 2097151 & (load_3(c + 13) >> 1);
crypto_int64 c6 = 2097151 & (load_4(c + 15) >> 6);
crypto_int64 c7 = 2097151 & (load_3(c + 18) >> 3);
crypto_int64 c8 = 2097151 & load_3(c + 21);
crypto_int64 c9 = 2097151 & (load_4(c + 23) >> 5);
crypto_int64 c10 = 2097151 & (load_3(c + 26) >> 2);
crypto_int64 c11 = (load_4(c + 28) >> 7);
crypto_int64 s0;
crypto_int64 s1;
crypto_int64 s2;
crypto_int64 s3;
crypto_int64 s4;
crypto_int64 s5;
crypto_int64 s6;
crypto_int64 s7;
crypto_int64 s8;
crypto_int64 s9;
crypto_int64 s10;
crypto_int64 s11;
crypto_int64 s12;
crypto_int64 s13;
crypto_int64 s14;
crypto_int64 s15;
crypto_int64 s16;
crypto_int64 s17;
crypto_int64 s18;
crypto_int64 s19;
crypto_int64 s20;
crypto_int64 s21;
crypto_int64 s22;
crypto_int64 s23;
crypto_int64 carry0;
crypto_int64 carry1;
crypto_int64 carry2;
crypto_int64 carry3;
crypto_int64 carry4;
crypto_int64 carry5;
crypto_int64 carry6;
crypto_int64 carry7;
crypto_int64 carry8;
crypto_int64 carry9;
crypto_int64 carry10;
crypto_int64 carry11;
crypto_int64 carry12;
crypto_int64 carry13;
crypto_int64 carry14;
crypto_int64 carry15;
crypto_int64 carry16;
crypto_int64 carry17;
crypto_int64 carry18;
crypto_int64 carry19;
crypto_int64 carry20;
crypto_int64 carry21;
crypto_int64 carry22;
s0 = c0 + a0*b0;
s1 = c1 + a0*b1 + a1*b0;
s2 = c2 + a0*b2 + a1*b1 + a2*b0;
s3 = c3 + a0*b3 + a1*b2 + a2*b1 + a3*b0;
s4 = c4 + a0*b4 + a1*b3 + a2*b2 + a3*b1 + a4*b0;
s5 = c5 + a0*b5 + a1*b4 + a2*b3 + a3*b2 + a4*b1 + a5*b0;
s6 = c6 + a0*b6 + a1*b5 + a2*b4 + a3*b3 + a4*b2 + a5*b1 + a6*b0;
s7 = c7 + a0*b7 + a1*b6 + a2*b5 + a3*b4 + a4*b3 + a5*b2 + a6*b1 + a7*b0;
s8 = c8 + a0*b8 + a1*b7 + a2*b6 + a3*b5 + a4*b4 + a5*b3 + a6*b2 + a7*b1 + a8*b0;
s9 = c9 + a0*b9 + a1*b8 + a2*b7 + a3*b6 + a4*b5 + a5*b4 + a6*b3 + a7*b2 + a8*b1 + a9*b0;
s10 = c10 + a0*b10 + a1*b9 + a2*b8 + a3*b7 + a4*b6 + a5*b5 + a6*b4 + a7*b3 + a8*b2 + a9*b1 + a10*b0;
s11 = c11 + a0*b11 + a1*b10 + a2*b9 + a3*b8 + a4*b7 + a5*b6 + a6*b5 + a7*b4 + a8*b3 + a9*b2 + a10*b1 + a11*b0;
s12 = a1*b11 + a2*b10 + a3*b9 + a4*b8 + a5*b7 + a6*b6 + a7*b5 + a8*b4 + a9*b3 + a10*b2 + a11*b1;
s13 = a2*b11 + a3*b10 + a4*b9 + a5*b8 + a6*b7 + a7*b6 + a8*b5 + a9*b4 + a10*b3 + a11*b2;
s14 = a3*b11 + a4*b10 + a5*b9 + a6*b8 + a7*b7 + a8*b6 + a9*b5 + a10*b4 + a11*b3;
s15 = a4*b11 + a5*b10 + a6*b9 + a7*b8 + a8*b7 + a9*b6 + a10*b5 + a11*b4;
s16 = a5*b11 + a6*b10 + a7*b9 + a8*b8 + a9*b7 + a10*b6 + a11*b5;
s17 = a6*b11 + a7*b10 + a8*b9 + a9*b8 + a10*b7 + a11*b6;
s18 = a7*b11 + a8*b10 + a9*b9 + a10*b8 + a11*b7;
s19 = a8*b11 + a9*b10 + a10*b9 + a11*b8;
s20 = a9*b11 + a10*b10 + a11*b9;
s21 = a10*b11 + a11*b10;
s22 = a11*b11;
s23 = 0;
carry0 = (s0 + (1<<20)) >> 21; s1 += carry0; s0 -= carry0 << 21;
carry2 = (s2 + (1<<20)) >> 21; s3 += carry2; s2 -= carry2 << 21;
carry4 = (s4 + (1<<20)) >> 21; s5 += carry4; s4 -= carry4 << 21;
carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21;
carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21;
carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21;
carry12 = (s12 + (1<<20)) >> 21; s13 += carry12; s12 -= carry12 << 21;
carry14 = (s14 + (1<<20)) >> 21; s15 += carry14; s14 -= carry14 << 21;
carry16 = (s16 + (1<<20)) >> 21; s17 += carry16; s16 -= carry16 << 21;
carry18 = (s18 + (1<<20)) >> 21; s19 += carry18; s18 -= carry18 << 21;
carry20 = (s20 + (1<<20)) >> 21; s21 += carry20; s20 -= carry20 << 21;
carry22 = (s22 + (1<<20)) >> 21; s23 += carry22; s22 -= carry22 << 21;
carry1 = (s1 + (1<<20)) >> 21; s2 += carry1; s1 -= carry1 << 21;
carry3 = (s3 + (1<<20)) >> 21; s4 += carry3; s3 -= carry3 << 21;
carry5 = (s5 + (1<<20)) >> 21; s6 += carry5; s5 -= carry5 << 21;
carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21;
carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21;
carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21;
carry13 = (s13 + (1<<20)) >> 21; s14 += carry13; s13 -= carry13 << 21;
carry15 = (s15 + (1<<20)) >> 21; s16 += carry15; s15 -= carry15 << 21;
carry17 = (s17 + (1<<20)) >> 21; s18 += carry17; s17 -= carry17 << 21;
carry19 = (s19 + (1<<20)) >> 21; s20 += carry19; s19 -= carry19 << 21;
carry21 = (s21 + (1<<20)) >> 21; s22 += carry21; s21 -= carry21 << 21;
s11 += s23 * 666643;
s12 += s23 * 470296;
s13 += s23 * 654183;
s14 -= s23 * 997805;
s15 += s23 * 136657;
s16 -= s23 * 683901;
s23 = 0;
s10 += s22 * 666643;
s11 += s22 * 470296;
s12 += s22 * 654183;
s13 -= s22 * 997805;
s14 += s22 * 136657;
s15 -= s22 * 683901;
s22 = 0;
s9 += s21 * 666643;
s10 += s21 * 470296;
s11 += s21 * 654183;
s12 -= s21 * 997805;
s13 += s21 * 136657;
s14 -= s21 * 683901;
s21 = 0;
s8 += s20 * 666643;
s9 += s20 * 470296;
s10 += s20 * 654183;
s11 -= s20 * 997805;
s12 += s20 * 136657;
s13 -= s20 * 683901;
s20 = 0;
s7 += s19 * 666643;
s8 += s19 * 470296;
s9 += s19 * 654183;
s10 -= s19 * 997805;
s11 += s19 * 136657;
s12 -= s19 * 683901;
s19 = 0;
s6 += s18 * 666643;
s7 += s18 * 470296;
s8 += s18 * 654183;
s9 -= s18 * 997805;
s10 += s18 * 136657;
s11 -= s18 * 683901;
s18 = 0;
carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21;
carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21;
carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21;
carry12 = (s12 + (1<<20)) >> 21; s13 += carry12; s12 -= carry12 << 21;
carry14 = (s14 + (1<<20)) >> 21; s15 += carry14; s14 -= carry14 << 21;
carry16 = (s16 + (1<<20)) >> 21; s17 += carry16; s16 -= carry16 << 21;
carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21;
carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21;
carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21;
carry13 = (s13 + (1<<20)) >> 21; s14 += carry13; s13 -= carry13 << 21;
carry15 = (s15 + (1<<20)) >> 21; s16 += carry15; s15 -= carry15 << 21;
s5 += s17 * 666643;
s6 += s17 * 470296;
s7 += s17 * 654183;
s8 -= s17 * 997805;
s9 += s17 * 136657;
s10 -= s17 * 683901;
s17 = 0;
s4 += s16 * 666643;
s5 += s16 * 470296;
s6 += s16 * 654183;
s7 -= s16 * 997805;
s8 += s16 * 136657;
s9 -= s16 * 683901;
s16 = 0;
s3 += s15 * 666643;
s4 += s15 * 470296;
s5 += s15 * 654183;
s6 -= s15 * 997805;
s7 += s15 * 136657;
s8 -= s15 * 683901;
s15 = 0;
s2 += s14 * 666643;
s3 += s14 * 470296;
s4 += s14 * 654183;
s5 -= s14 * 997805;
s6 += s14 * 136657;
s7 -= s14 * 683901;
s14 = 0;
s1 += s13 * 666643;
s2 += s13 * 470296;
s3 += s13 * 654183;
s4 -= s13 * 997805;
s5 += s13 * 136657;
s6 -= s13 * 683901;
s13 = 0;
s0 += s12 * 666643;
s1 += s12 * 470296;
s2 += s12 * 654183;
s3 -= s12 * 997805;
s4 += s12 * 136657;
s5 -= s12 * 683901;
s12 = 0;
carry0 = (s0 + (1<<20)) >> 21; s1 += carry0; s0 -= carry0 << 21;
carry2 = (s2 + (1<<20)) >> 21; s3 += carry2; s2 -= carry2 << 21;
carry4 = (s4 + (1<<20)) >> 21; s5 += carry4; s4 -= carry4 << 21;
carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21;
carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21;
carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21;
carry1 = (s1 + (1<<20)) >> 21; s2 += carry1; s1 -= carry1 << 21;
carry3 = (s3 + (1<<20)) >> 21; s4 += carry3; s3 -= carry3 << 21;
carry5 = (s5 + (1<<20)) >> 21; s6 += carry5; s5 -= carry5 << 21;
carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21;
carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21;
carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21;
s0 += s12 * 666643;
s1 += s12 * 470296;
s2 += s12 * 654183;
s3 -= s12 * 997805;
s4 += s12 * 136657;
s5 -= s12 * 683901;
s12 = 0;
carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21;
carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21;
carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21;
carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21;
carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21;
carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21;
carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21;
carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21;
carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21;
carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21;
carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21;
carry11 = s11 >> 21; s12 += carry11; s11 -= carry11 << 21;
s0 += s12 * 666643;
s1 += s12 * 470296;
s2 += s12 * 654183;
s3 -= s12 * 997805;
s4 += s12 * 136657;
s5 -= s12 * 683901;
s12 = 0;
carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21;
carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21;
carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21;
carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21;
carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21;
carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21;
carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21;
carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21;
carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21;
carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21;
carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21;
s[0] = s0 >> 0;
s[1] = s0 >> 8;
s[2] = (s0 >> 16) | (s1 << 5);
s[3] = s1 >> 3;
s[4] = s1 >> 11;
s[5] = (s1 >> 19) | (s2 << 2);
s[6] = s2 >> 6;
s[7] = (s2 >> 14) | (s3 << 7);
s[8] = s3 >> 1;
s[9] = s3 >> 9;
s[10] = (s3 >> 17) | (s4 << 4);
s[11] = s4 >> 4;
s[12] = s4 >> 12;
s[13] = (s4 >> 20) | (s5 << 1);
s[14] = s5 >> 7;
s[15] = (s5 >> 15) | (s6 << 6);
s[16] = s6 >> 2;
s[17] = s6 >> 10;
s[18] = (s6 >> 18) | (s7 << 3);
s[19] = s7 >> 5;
s[20] = s7 >> 13;
s[21] = s8 >> 0;
s[22] = s8 >> 8;
s[23] = (s8 >> 16) | (s9 << 5);
s[24] = s9 >> 3;
s[25] = s9 >> 11;
s[26] = (s9 >> 19) | (s10 << 2);
s[27] = s10 >> 6;
s[28] = (s10 >> 14) | (s11 << 7);
s[29] = s11 >> 1;
s[30] = s11 >> 9;
s[31] = s11 >> 17;
}

View File

@ -0,0 +1,275 @@
#include "sc.h"
#include "crypto_int64.h"
#include "crypto_uint32.h"
#include "crypto_uint64.h"
static crypto_uint64 load_3(const unsigned char *in)
{
crypto_uint64 result;
result = (crypto_uint64) in[0];
result |= ((crypto_uint64) in[1]) << 8;
result |= ((crypto_uint64) in[2]) << 16;
return result;
}
static crypto_uint64 load_4(const unsigned char *in)
{
crypto_uint64 result;
result = (crypto_uint64) in[0];
result |= ((crypto_uint64) in[1]) << 8;
result |= ((crypto_uint64) in[2]) << 16;
result |= ((crypto_uint64) in[3]) << 24;
return result;
}
/*
Input:
s[0]+256*s[1]+...+256^63*s[63] = s
Output:
s[0]+256*s[1]+...+256^31*s[31] = s mod l
where l = 2^252 + 27742317777372353535851937790883648493.
Overwrites s in place.
*/
void sc_reduce(unsigned char *s)
{
crypto_int64 s0 = 2097151 & load_3(s);
crypto_int64 s1 = 2097151 & (load_4(s + 2) >> 5);
crypto_int64 s2 = 2097151 & (load_3(s + 5) >> 2);
crypto_int64 s3 = 2097151 & (load_4(s + 7) >> 7);
crypto_int64 s4 = 2097151 & (load_4(s + 10) >> 4);
crypto_int64 s5 = 2097151 & (load_3(s + 13) >> 1);
crypto_int64 s6 = 2097151 & (load_4(s + 15) >> 6);
crypto_int64 s7 = 2097151 & (load_3(s + 18) >> 3);
crypto_int64 s8 = 2097151 & load_3(s + 21);
crypto_int64 s9 = 2097151 & (load_4(s + 23) >> 5);
crypto_int64 s10 = 2097151 & (load_3(s + 26) >> 2);
crypto_int64 s11 = 2097151 & (load_4(s + 28) >> 7);
crypto_int64 s12 = 2097151 & (load_4(s + 31) >> 4);
crypto_int64 s13 = 2097151 & (load_3(s + 34) >> 1);
crypto_int64 s14 = 2097151 & (load_4(s + 36) >> 6);
crypto_int64 s15 = 2097151 & (load_3(s + 39) >> 3);
crypto_int64 s16 = 2097151 & load_3(s + 42);
crypto_int64 s17 = 2097151 & (load_4(s + 44) >> 5);
crypto_int64 s18 = 2097151 & (load_3(s + 47) >> 2);
crypto_int64 s19 = 2097151 & (load_4(s + 49) >> 7);
crypto_int64 s20 = 2097151 & (load_4(s + 52) >> 4);
crypto_int64 s21 = 2097151 & (load_3(s + 55) >> 1);
crypto_int64 s22 = 2097151 & (load_4(s + 57) >> 6);
crypto_int64 s23 = (load_4(s + 60) >> 3);
crypto_int64 carry0;
crypto_int64 carry1;
crypto_int64 carry2;
crypto_int64 carry3;
crypto_int64 carry4;
crypto_int64 carry5;
crypto_int64 carry6;
crypto_int64 carry7;
crypto_int64 carry8;
crypto_int64 carry9;
crypto_int64 carry10;
crypto_int64 carry11;
crypto_int64 carry12;
crypto_int64 carry13;
crypto_int64 carry14;
crypto_int64 carry15;
crypto_int64 carry16;
s11 += s23 * 666643;
s12 += s23 * 470296;
s13 += s23 * 654183;
s14 -= s23 * 997805;
s15 += s23 * 136657;
s16 -= s23 * 683901;
s23 = 0;
s10 += s22 * 666643;
s11 += s22 * 470296;
s12 += s22 * 654183;
s13 -= s22 * 997805;
s14 += s22 * 136657;
s15 -= s22 * 683901;
s22 = 0;
s9 += s21 * 666643;
s10 += s21 * 470296;
s11 += s21 * 654183;
s12 -= s21 * 997805;
s13 += s21 * 136657;
s14 -= s21 * 683901;
s21 = 0;
s8 += s20 * 666643;
s9 += s20 * 470296;
s10 += s20 * 654183;
s11 -= s20 * 997805;
s12 += s20 * 136657;
s13 -= s20 * 683901;
s20 = 0;
s7 += s19 * 666643;
s8 += s19 * 470296;
s9 += s19 * 654183;
s10 -= s19 * 997805;
s11 += s19 * 136657;
s12 -= s19 * 683901;
s19 = 0;
s6 += s18 * 666643;
s7 += s18 * 470296;
s8 += s18 * 654183;
s9 -= s18 * 997805;
s10 += s18 * 136657;
s11 -= s18 * 683901;
s18 = 0;
carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21;
carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21;
carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21;
carry12 = (s12 + (1<<20)) >> 21; s13 += carry12; s12 -= carry12 << 21;
carry14 = (s14 + (1<<20)) >> 21; s15 += carry14; s14 -= carry14 << 21;
carry16 = (s16 + (1<<20)) >> 21; s17 += carry16; s16 -= carry16 << 21;
carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21;
carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21;
carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21;
carry13 = (s13 + (1<<20)) >> 21; s14 += carry13; s13 -= carry13 << 21;
carry15 = (s15 + (1<<20)) >> 21; s16 += carry15; s15 -= carry15 << 21;
s5 += s17 * 666643;
s6 += s17 * 470296;
s7 += s17 * 654183;
s8 -= s17 * 997805;
s9 += s17 * 136657;
s10 -= s17 * 683901;
s17 = 0;
s4 += s16 * 666643;
s5 += s16 * 470296;
s6 += s16 * 654183;
s7 -= s16 * 997805;
s8 += s16 * 136657;
s9 -= s16 * 683901;
s16 = 0;
s3 += s15 * 666643;
s4 += s15 * 470296;
s5 += s15 * 654183;
s6 -= s15 * 997805;
s7 += s15 * 136657;
s8 -= s15 * 683901;
s15 = 0;
s2 += s14 * 666643;
s3 += s14 * 470296;
s4 += s14 * 654183;
s5 -= s14 * 997805;
s6 += s14 * 136657;
s7 -= s14 * 683901;
s14 = 0;
s1 += s13 * 666643;
s2 += s13 * 470296;
s3 += s13 * 654183;
s4 -= s13 * 997805;
s5 += s13 * 136657;
s6 -= s13 * 683901;
s13 = 0;
s0 += s12 * 666643;
s1 += s12 * 470296;
s2 += s12 * 654183;
s3 -= s12 * 997805;
s4 += s12 * 136657;
s5 -= s12 * 683901;
s12 = 0;
carry0 = (s0 + (1<<20)) >> 21; s1 += carry0; s0 -= carry0 << 21;
carry2 = (s2 + (1<<20)) >> 21; s3 += carry2; s2 -= carry2 << 21;
carry4 = (s4 + (1<<20)) >> 21; s5 += carry4; s4 -= carry4 << 21;
carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21;
carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21;
carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21;
carry1 = (s1 + (1<<20)) >> 21; s2 += carry1; s1 -= carry1 << 21;
carry3 = (s3 + (1<<20)) >> 21; s4 += carry3; s3 -= carry3 << 21;
carry5 = (s5 + (1<<20)) >> 21; s6 += carry5; s5 -= carry5 << 21;
carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21;
carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21;
carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21;
s0 += s12 * 666643;
s1 += s12 * 470296;
s2 += s12 * 654183;
s3 -= s12 * 997805;
s4 += s12 * 136657;
s5 -= s12 * 683901;
s12 = 0;
carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21;
carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21;
carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21;
carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21;
carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21;
carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21;
carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21;
carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21;
carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21;
carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21;
carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21;
carry11 = s11 >> 21; s12 += carry11; s11 -= carry11 << 21;
s0 += s12 * 666643;
s1 += s12 * 470296;
s2 += s12 * 654183;
s3 -= s12 * 997805;
s4 += s12 * 136657;
s5 -= s12 * 683901;
s12 = 0;
carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21;
carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21;
carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21;
carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21;
carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21;
carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21;
carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21;
carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21;
carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21;
carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21;
carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21;
s[0] = s0 >> 0;
s[1] = s0 >> 8;
s[2] = (s0 >> 16) | (s1 << 5);
s[3] = s1 >> 3;
s[4] = s1 >> 11;
s[5] = (s1 >> 19) | (s2 << 2);
s[6] = s2 >> 6;
s[7] = (s2 >> 14) | (s3 << 7);
s[8] = s3 >> 1;
s[9] = s3 >> 9;
s[10] = (s3 >> 17) | (s4 << 4);
s[11] = s4 >> 4;
s[12] = s4 >> 12;
s[13] = (s4 >> 20) | (s5 << 1);
s[14] = s5 >> 7;
s[15] = (s5 >> 15) | (s6 << 6);
s[16] = s6 >> 2;
s[17] = s6 >> 10;
s[18] = (s6 >> 18) | (s7 << 3);
s[19] = s7 >> 5;
s[20] = s7 >> 13;
s[21] = s8 >> 0;
s[22] = s8 >> 8;
s[23] = (s8 >> 16) | (s9 << 5);
s[24] = s9 >> 3;
s[25] = s9 >> 11;
s[26] = (s9 >> 19) | (s10 << 2);
s[27] = s10 >> 6;
s[28] = (s10 >> 14) | (s11 << 7);
s[29] = s11 >> 1;
s[30] = s11 >> 9;
s[31] = s11 >> 17;
}

View File

@ -0,0 +1,34 @@
#include <string.h>
#include "crypto_sign.h"
#include "crypto_hash_sha512.h"
#include "ge.h"
#include "sc.h"
int crypto_sign(
unsigned char *sig,
const unsigned char* m, size_t mlen,
const unsigned char* sk, const unsigned char* pk
)
{
unsigned char az[64];
unsigned char nonce[64];
unsigned char hram[64];
ge_p3 R;
crypto_hash_sha512(az,sk,32);
az[0] &= 248;
az[31] &= 63;
az[31] |= 64;
crypto_hash_sha512_2(nonce, az + 32, 32, m, mlen);
sc_reduce(nonce);
ge_scalarmult_base(&R,nonce);
ge_p3_tobytes(sig,&R);
crypto_hash_sha512_3(hram, sig, 32, pk, 32, m, mlen);
sc_reduce(hram);
sc_muladd(sig + 32,hram,az,nonce);
return 0;
}

View File

@ -0,0 +1 @@
-32595792,-7943725,9377950,3500415,12389472,-272473,-25146209,-2005654,326686,11406482

View File

@ -0,0 +1,28 @@
q = 2**255 - 19
def expmod(b,e,m):
if e == 0: return 1
t = expmod(b,e/2,m)**2 % m
if e & 1: t = (t*b) % m
return t
def inv(x):
return expmod(x,q-2,q)
def radix255(x):
x = x % q
if x + x > q: x -= q
x = [x,0,0,0,0,0,0,0,0,0]
bits = [26,25,26,25,26,25,26,25,26,25]
for i in range(9):
carry = (x[i] + 2**(bits[i]-1)) / 2**bits[i]
x[i] -= carry * 2**bits[i]
x[i + 1] += carry
result = ""
for i in range(9):
result = result+str(x[i])+","
result = result+str(x[9])
return result
I = expmod(2,(q-1)/4,q)
print radix255(I)

View File

@ -138,7 +138,7 @@ namespace transport
}
}
void NTCPSession::HandlePhase1Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred)
void NTCPSession::HandlePhase1Sent (const boost::system::error_code& ecode, std::size_t)
{
if (ecode)
{
@ -154,7 +154,7 @@ namespace transport
}
}
void NTCPSession::HandlePhase1Received (const boost::system::error_code& ecode, std::size_t bytes_transferred)
void NTCPSession::HandlePhase1Received (const boost::system::error_code& ecode, std::size_t)
{
if (ecode)
{
@ -209,7 +209,7 @@ namespace transport
}
void NTCPSession::HandlePhase2Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsB)
void NTCPSession::HandlePhase2Sent (const boost::system::error_code& ecode, std::size_t, uint32_t tsB)
{
if (ecode)
{
@ -225,7 +225,7 @@ namespace transport
}
}
void NTCPSession::HandlePhase2Received (const boost::system::error_code& ecode, std::size_t bytes_transferred)
void NTCPSession::HandlePhase2Received (const boost::system::error_code& ecode, std::size_t)
{
if (ecode)
{
@ -299,7 +299,7 @@ namespace transport
std::bind(&NTCPSession::HandlePhase3Sent, shared_from_this (), std::placeholders::_1, std::placeholders::_2, tsA));
}
void NTCPSession::HandlePhase3Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred, uint32_t tsA)
void NTCPSession::HandlePhase3Sent (const boost::system::error_code& ecode, std::size_t, uint32_t tsA)
{
if (ecode)
{
@ -412,7 +412,7 @@ namespace transport
std::bind(&NTCPSession::HandlePhase4Sent, shared_from_this (), std::placeholders::_1, std::placeholders::_2));
}
void NTCPSession::HandlePhase4Sent (const boost::system::error_code& ecode, std::size_t bytes_transferred)
void NTCPSession::HandlePhase4Sent (const boost::system::error_code& ecode, std::size_t)
{
if (ecode)
{
@ -643,7 +643,7 @@ namespace transport
std::bind(&NTCPSession::HandleSent, shared_from_this (), std::placeholders::_1, std::placeholders::_2, msgs));
}
void NTCPSession::HandleSent (const boost::system::error_code& ecode, std::size_t bytes_transferred, std::vector<std::shared_ptr<I2NPMessage> > msgs)
void NTCPSession::HandleSent (const boost::system::error_code& ecode, std::size_t bytes_transferred, std::vector<std::shared_ptr<I2NPMessage> >)
{
m_IsSending = false;
if (ecode)
@ -710,7 +710,7 @@ namespace transport
}
//-----------------------------------------
NTCPServer::NTCPServer (int port):
NTCPServer::NTCPServer (int):
m_IsRunning (false), m_Thread (nullptr), m_Work (m_Service),
m_NTCPAcceptor (nullptr), m_NTCPV6Acceptor (nullptr)
{

View File

@ -172,7 +172,7 @@ namespace transport
}
}
void SSUSession::ProcessSessionRequest (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& senderEndpoint)
void SSUSession::ProcessSessionRequest (uint8_t * buf, size_t, const boost::asio::ip::udp::endpoint& senderEndpoint)
{
LogPrint (eLogDebug, "Session request received");
m_RemoteEndpoint = senderEndpoint;
@ -182,7 +182,7 @@ namespace transport
SendSessionCreated (buf + sizeof (SSUHeader));
}
void SSUSession::ProcessSessionCreated (uint8_t * buf, size_t len)
void SSUSession::ProcessSessionCreated (uint8_t * buf, size_t)
{
if (!m_RemoteRouter || !m_DHKeysPair)
{
@ -246,7 +246,7 @@ namespace transport
SendSessionConfirmed (y, ourAddress, addressSize + 2);
}
void SSUSession::ProcessSessionConfirmed (uint8_t * buf, size_t len)
void SSUSession::ProcessSessionConfirmed (uint8_t * buf, size_t)
{
LogPrint (eLogDebug, "Session confirmed received");
uint8_t * payload = buf + sizeof (SSUHeader);
@ -450,7 +450,7 @@ namespace transport
Send (buf, msgLen);
}
void SSUSession::ProcessRelayRequest (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& from)
void SSUSession::ProcessRelayRequest (uint8_t * buf, size_t, const boost::asio::ip::udp::endpoint& from)
{
uint32_t relayTag = bufbe32toh (buf);
auto session = m_Server.FindRelaySession (relayTag);
@ -553,7 +553,7 @@ namespace transport
LogPrint (eLogDebug, "SSU relay intro sent");
}
void SSUSession::ProcessRelayResponse (uint8_t * buf, size_t len)
void SSUSession::ProcessRelayResponse (uint8_t * buf, size_t)
{
LogPrint (eLogDebug, "Relay response received");
uint8_t * payload = buf + sizeof (SSUHeader);
@ -585,7 +585,7 @@ namespace transport
i2p::context.UpdateAddress (ourIP);
}
void SSUSession::ProcessRelayIntro (uint8_t * buf, size_t len)
void SSUSession::ProcessRelayIntro (uint8_t * buf, size_t)
{
uint8_t size = *buf;
if (size == 4)

Some files were not shown because too many files have changed in this diff Show More