Bundle TAP installer with main installer instead of downloading

This commit is contained in:
Ludvig Strigeus 2018-10-21 23:47:47 +02:00
parent 7afef3865f
commit 29473fe75a
36 changed files with 5 additions and 4090 deletions

View file

@ -24,6 +24,7 @@ Changes:
10.IPv6 endpoint was printed incorrectly on the Advanced tab
11.Show an error message and drop packets if the TUN queue grows
too large. This is a problem with the TAP NDIS6 driver on Win7.
12.Bundle the TunSafe-TAP installer instead of downloading it.
2018-10-08 - TunSafe v1.4

Binary file not shown.

View file

@ -1,3 +0,0 @@
/Debug/
/Release/
/.vs/

Binary file not shown.

View file

@ -1,104 +0,0 @@
import hashlib
b = 256
q = 2**255 - 19
l = 2**252 + 27742317777372353535851937790883648493
def H(m):
return hashlib.sha512(m).digest()
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 scalarmult(P,e):
if e == 0: return [0,1]
Q = scalarmult(P,e/2)
Q = edwards(Q,Q)
if e & 1: Q = edwards(Q,P)
return Q
def encodeint(y):
bits = [(y >> i) & 1 for i in range(b)]
return ''.join([chr(sum([bits[i * 8 + j] << j for j in range(8)])) for i in range(b/8)])
def encodepoint(P):
x = P[0]
y = P[1]
bits = [(y >> i) & 1 for i in range(b - 1)] + [x & 1]
return ''.join([chr(sum([bits[i * 8 + j] << j for j in range(8)])) for i in range(b/8)])
def bit(h,i):
return (ord(h[i/8]) >> (i%8)) & 1
def publickey(sk):
h = H(sk)
a = 2**(b-2) + sum(2**i * bit(h,i) for i in range(3,b-2))
A = scalarmult(B,a)
return encodepoint(A)
def Hint(m):
h = H(m)
return sum(2**i * bit(h,i) for i in range(2*b))
def signature(m,sk,pk):
h = H(sk)
a = 2**(b-2) + sum(2**i * bit(h,i) for i in range(3,b-2))
r = Hint(''.join([h[i] for i in range(b/8,b/4)]) + m)
R = scalarmult(B,r)
S = (r + Hint(encodepoint(R) + pk + m) * a) % l
return encodepoint(R) + encodeint(S)
def isoncurve(P):
x = P[0]
y = P[1]
return (-x*x + y*y - 1 - d*x*x*y*y) % q == 0
def decodeint(s):
return sum(2**i * bit(s,i) for i in range(0,b))
def decodepoint(s):
y = sum(2**i * bit(s,i) for i in range(0,b-1))
x = xrecover(y)
if x & 1 != bit(s,b-1): x = q-x
P = [x,y]
if not isoncurve(P): raise Exception("decoding point that is not on curve")
return P
def checkvalid(s,m,pk):
if len(s) != b/4: raise Exception("signature length is wrong")
if len(pk) != b/8: raise Exception("public-key length is wrong")
R = decodepoint(s[0:b/8])
A = decodepoint(pk)
S = decodeint(s[b/8:b/4])
h = Hint(encodepoint(R) + pk + m)
if scalarmult(B,S) != edwards(R,scalarmult(A,h)):
raise Exception("signature does not pass verification")

View file

@ -1,26 +0,0 @@
import hashlib, json
def H(m):
return hashlib.sha512(m).digest()
import ed25519
import os
# Load signing keys from location outside of repo
keys = json.loads(file('../../../misc/config/installer_signing_key.json', 'r').read())
def tobin(xs):
return "".join(chr(x) for x in xs)
def gen_key():
sk = os.urandom(32)
pk = ed25519.publickey(sk)
print 'sk', [ord(c) for c in sk]
print 'pk', [ord(c) for c in pk]
hash = H(file('../tap/TunSafe-TAP-auto.exe', 'rb').read())
print hash.encode('hex'), repr(hash)
#m = 'test'
s = ed25519.signature(hash, tobin(keys['PRIVATE_KEY']), tobin(keys['PUBLIC_KEY']))
file('../tap/TunSafe-TAP-auto.exe.sig', 'wb').write(s.encode('hex'))

View file

@ -1,118 +0,0 @@
#include <Windows.h>
extern "C" {
#include "tiny/edsign.h"
#include "nsis/pluginapi.h"
#include "tiny/sha512.h"
}
// To work with Unicode version of NSIS, please use TCHAR-type
// functions for accessing the variables and the stack.
unsigned char buffer[4096];
#include "../../../misc/config/installer_signing_key_pub.h"
int CheckFile(char *file) {
sha512_state ctx;
int ret;
HANDLE h;
unsigned char out[64];
unsigned char signature[64];
h = CreateFileA(file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (h == INVALID_HANDLE_VALUE)
return 1;
DWORD n;
sha512_init(&ctx);
size_t total_size = 0;
size_t p = 0;
while (ReadFile(h, buffer, sizeof(buffer), &n, NULL) && n) {
total_size += n;
p = 0;
while (p + 128 <= n) {
sha512_block(&ctx, buffer + p);
p += 128;
}
if (p != n)
break;
}
sha512_final(&ctx, buffer + p, total_size);
sha512_get(&ctx, out, 0, 64);
CloseHandle(h);
/*
for (size_t i = 0; i < 64; i++) {
buffer[i * 2 + 0] = "0123456789abcdef"[out[i] >> 4];
buffer[i * 2 + 1] = "0123456789abcdef"[out[i] & 0xF];
}
buffer[128] = 0;
MessageBoxA(0, (char*)buffer, "sha", 0);
*/
char *x = file;
while (*x)x++;
memcpy(x, ".sig", 5);
h = CreateFileA(file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (h == INVALID_HANDLE_VALUE)
return 2;
n = 0;
ReadFile(h, buffer, sizeof(buffer), &n, NULL);
CloseHandle(h);
if (n < 128)
return 3;
memset(signature, 0, sizeof(signature));
for (int i = 0; i < 128; i++) {
unsigned char c = buffer[i];
if (c >= '0' && c <= '9')
c -= '0';
else if ((c |= 32), c >= 'a' && c <= 'f')
c -= 'a' - 10;
else
return 4;
signature[i >> 1] = (signature[i >> 1] << 4) + c;
}
/* create a random seed, and a keypair out of that seed */
//ed25519_create_seed(seed);
//ed25519_create_keypair(public_key, private_key, seed);
/* create signature on the message with the keypair */
//ed25519_sign(signature, message, message_len, public_key, private_key);
/* verify the signature */
return edsign_verify(signature, pk, out, sizeof(out)) ? 0 : 5;
}
extern "C" void __declspec(dllexport) myFunction(HWND hwndParent, int string_size,
LPTSTR variables, stack_t **stacktop,
extra_parameters *extra, ...) {
EXDLL_INIT();
int rv = 10;
// note if you want parameters from the stack, pop them off in order.
// i.e. if you are called via exdll::myFunction file.dat read.txt
// calling popstring() the first time would give you file.dat,
// and the second time would give you read.txt.
// you should empty the stack of your parameters, and ONLY your
// parameters.
// do your stuff here
{
LPTSTR msgbuf = (LPTSTR)GlobalAlloc(GPTR, (string_size + 1 + 10) * sizeof(*msgbuf));
if (msgbuf) {
if (!popstring(msgbuf)) {
rv = CheckFile(msgbuf);
}
GlobalFree(msgbuf);
}
}
pushint(rv);
}
BOOL WINAPI DllMain(HINSTANCE hInst, ULONG ul_reason_for_call, LPVOID lpReserved) {
return TRUE;
}

View file

@ -1,85 +0,0 @@
/*
* apih
*
* This file is a part of NSIS.
*
* Copyright (C) 1999-2018 Nullsoft and Contributors
*
* Licensed under the zlib/libpng license (the "License");
* you may not use this file except in compliance with the License.
*
* Licence details can be found in the file COPYING.
*
* This software is provided 'as-is', without any express or implied
* warranty.
*/
#ifndef _NSIS_EXEHEAD_API_H_
#define _NSIS_EXEHEAD_API_H_
// Starting with NSIS 2.42, you can check the version of the plugin API in exec_flags->plugin_api_version
// The format is 0xXXXXYYYY where X is the major version and Y is the minor version (MAKELONG(y,x))
// When doing version checks, always remember to use >=, ex: if (pX->exec_flags->plugin_api_version >= NSISPIAPIVER_1_0) {}
#define NSISPIAPIVER_1_0 0x00010000
#define NSISPIAPIVER_CURR NSISPIAPIVER_1_0
// NSIS Plug-In Callback Messages
enum NSPIM
{
NSPIM_UNLOAD, // This is the last message a plugin gets, do final cleanup
NSPIM_GUIUNLOAD, // Called after .onGUIEnd
};
// Prototype for callbacks registered with extra_parameters->RegisterPluginCallback()
// Return NULL for unknown messages
// Should always be __cdecl for future expansion possibilities
typedef UINT_PTR (*NSISPLUGINCALLBACK)(enum NSPIM);
// extra_parameters data structure containing other interesting stuff
// besides the stack, variables and HWND passed on to plug-ins.
typedef struct
{
int autoclose; // SetAutoClose
int all_user_var; // SetShellVarContext: User context = 0, Machine context = 1
int exec_error; // IfErrors
int abort; // IfAbort
int exec_reboot; // IfRebootFlag (NSIS_SUPPORT_REBOOT)
int reboot_called; // NSIS_SUPPORT_REBOOT
int XXX_cur_insttype; // Deprecated
int plugin_api_version; // Plug-in ABI. See NSISPIAPIVER_CURR (Note: used to be XXX_insttype_changed)
int silent; // IfSilent (NSIS_CONFIG_SILENT_SUPPORT)
int instdir_error; // GetInstDirError
int rtl; // 1 if $LANGUAGE is a RTL language
int errlvl; // SetErrorLevel
int alter_reg_view; // SetRegView: Default View = 0, Alternative View = (sizeof(void*) > 4 ? KEY_WOW64_32KEY : KEY_WOW64_64KEY)
int status_update; // SetDetailsPrint
} exec_flags_t;
#ifndef NSISCALL
# define NSISCALL __stdcall
#endif
#if !defined(_WIN32) && !defined(LPTSTR)
# define LPTSTR TCHAR*
#endif
typedef struct {
exec_flags_t *exec_flags;
int (NSISCALL *ExecuteCodeSegment)(int, HWND);
void (NSISCALL *validate_filename)(LPTSTR);
int (NSISCALL *RegisterPluginCallback)(HMODULE, NSISPLUGINCALLBACK); // returns 0 on success, 1 if already registered and < 0 on errors
} extra_parameters;
// Definitions for page showing plug-ins
// See Ui.c to understand better how they're used
// sent to the outer window to tell it to go to the next inner window
#define WM_NOTIFY_OUTER_NEXT (WM_USER+0x8)
// custom pages should send this message to let NSIS know they're ready
#define WM_NOTIFY_CUSTOM_READY (WM_USER+0xd)
// sent as wParam with WM_NOTIFY_OUTER_NEXT when user cancels - heed its warning
#define NOTIFY_BYE_BYE 'x'
#endif /* _NSIS_EXEHEAD_API_H_ */

View file

@ -1,229 +0,0 @@
/*
* nsis_tchar.h
*
* This file is a part of NSIS.
*
* Copyright (C) 1999-2018 Nullsoft and Contributors
*
* This software is provided 'as-is', without any express or implied
* warranty.
*
* For Unicode support by Jim Park -- 08/30/2007
*/
// Jim Park: Only those we use are listed here.
#pragma once
#ifdef _UNICODE
#ifndef _T
#define __T(x) L ## x
#define _T(x) __T(x)
#define _TEXT(x) __T(x)
#endif
#ifndef _TCHAR_DEFINED
#define _TCHAR_DEFINED
#if !defined(_NATIVE_WCHAR_T_DEFINED) && !defined(_WCHAR_T_DEFINED)
typedef unsigned short TCHAR;
#else
typedef wchar_t TCHAR;
#endif
#endif
// program
#define _tenviron _wenviron
#define __targv __wargv
// printfs
#define _ftprintf fwprintf
#define _sntprintf _snwprintf
#if (defined(_MSC_VER) && (_MSC_VER<=1310||_MSC_FULL_VER<=140040310)) || defined(__MINGW32__)
# define _stprintf swprintf
#else
# define _stprintf _swprintf
#endif
#define _tprintf wprintf
#define _vftprintf vfwprintf
#define _vsntprintf _vsnwprintf
#if defined(_MSC_VER) && (_MSC_VER<=1310)
# define _vstprintf vswprintf
#else
# define _vstprintf _vswprintf
#endif
// scanfs
#define _tscanf wscanf
#define _stscanf swscanf
// string manipulations
#define _tcscat wcscat
#define _tcschr wcschr
#define _tcsclen wcslen
#define _tcscpy wcscpy
#define _tcsdup _wcsdup
#define _tcslen wcslen
#define _tcsnccpy wcsncpy
#define _tcsncpy wcsncpy
#define _tcsrchr wcsrchr
#define _tcsstr wcsstr
#define _tcstok wcstok
// string comparisons
#define _tcscmp wcscmp
#define _tcsicmp _wcsicmp
#define _tcsncicmp _wcsnicmp
#define _tcsncmp wcsncmp
#define _tcsnicmp _wcsnicmp
// upper / lower
#define _tcslwr _wcslwr
#define _tcsupr _wcsupr
#define _totlower towlower
#define _totupper towupper
// conversions to numbers
#define _tcstoi64 _wcstoi64
#define _tcstol wcstol
#define _tcstoul wcstoul
#define _tstof _wtof
#define _tstoi _wtoi
#define _tstoi64 _wtoi64
#define _ttoi _wtoi
#define _ttoi64 _wtoi64
#define _ttol _wtol
// conversion from numbers to strings
#define _itot _itow
#define _ltot _ltow
#define _i64tot _i64tow
#define _ui64tot _ui64tow
// file manipulations
#define _tfopen _wfopen
#define _topen _wopen
#define _tremove _wremove
#define _tunlink _wunlink
// reading and writing to i/o
#define _fgettc fgetwc
#define _fgetts fgetws
#define _fputts fputws
#define _gettchar getwchar
// directory
#define _tchdir _wchdir
// environment
#define _tgetenv _wgetenv
#define _tsystem _wsystem
// time
#define _tcsftime wcsftime
#else // ANSI
#ifndef _T
#define _T(x) x
#define _TEXT(x) x
#endif
#ifndef _TCHAR_DEFINED
#define _TCHAR_DEFINED
typedef char TCHAR;
#endif
// program
#define _tenviron environ
#define __targv __argv
// printfs
#define _ftprintf fprintf
#define _sntprintf _snprintf
#define _stprintf sprintf
#define _tprintf printf
#define _vftprintf vfprintf
#define _vsntprintf _vsnprintf
#define _vstprintf vsprintf
// scanfs
#define _tscanf scanf
#define _stscanf sscanf
// string manipulations
#define _tcscat strcat
#define _tcschr strchr
#define _tcsclen strlen
#define _tcscnlen strnlen
#define _tcscpy strcpy
#define _tcsdup _strdup
#define _tcslen strlen
#define _tcsnccpy strncpy
#define _tcsrchr strrchr
#define _tcsstr strstr
#define _tcstok strtok
// string comparisons
#define _tcscmp strcmp
#define _tcsicmp _stricmp
#define _tcsncmp strncmp
#define _tcsncicmp _strnicmp
#define _tcsnicmp _strnicmp
// upper / lower
#define _tcslwr _strlwr
#define _tcsupr _strupr
#define _totupper toupper
#define _totlower tolower
// conversions to numbers
#define _tcstol strtol
#define _tcstoul strtoul
#define _tstof atof
#define _tstoi atoi
#define _tstoi64 _atoi64
#define _tstoi64 _atoi64
#define _ttoi atoi
#define _ttoi64 _atoi64
#define _ttol atol
// conversion from numbers to strings
#define _i64tot _i64toa
#define _itot _itoa
#define _ltot _ltoa
#define _ui64tot _ui64toa
// file manipulations
#define _tfopen fopen
#define _topen _open
#define _tremove remove
#define _tunlink _unlink
// reading and writing to i/o
#define _fgettc fgetc
#define _fgetts fgets
#define _fputts fputs
#define _gettchar getchar
// directory
#define _tchdir _chdir
// environment
#define _tgetenv getenv
#define _tsystem system
// time
#define _tcsftime strftime
#endif
// is functions (the same in Unicode / ANSI)
#define _istgraph isgraph
#define _istascii __isascii
#define __TFILE__ _T(__FILE__)
#define __TDATE__ _T(__DATE__)
#define __TTIME__ _T(__TIME__)

View file

@ -1,108 +0,0 @@
#ifndef ___NSIS_PLUGIN__H___
#define ___NSIS_PLUGIN__H___
#ifdef __cplusplus
extern "C" {
#endif
#include "api.h"
#include "nsis_tchar.h" // BUGBUG: Why cannot our plugins use the compilers tchar.h?
#ifndef NSISCALL
# define NSISCALL WINAPI
#endif
#define EXDLL_INIT() { \
g_stringsize=string_size; \
g_stacktop=stacktop; \
g_variables=variables; }
typedef struct _stack_t {
struct _stack_t *next;
#ifdef UNICODE
WCHAR text[1]; // this should be the length of g_stringsize when allocating
#else
char text[1];
#endif
} stack_t;
enum
{
INST_0, // $0
INST_1, // $1
INST_2, // $2
INST_3, // $3
INST_4, // $4
INST_5, // $5
INST_6, // $6
INST_7, // $7
INST_8, // $8
INST_9, // $9
INST_R0, // $R0
INST_R1, // $R1
INST_R2, // $R2
INST_R3, // $R3
INST_R4, // $R4
INST_R5, // $R5
INST_R6, // $R6
INST_R7, // $R7
INST_R8, // $R8
INST_R9, // $R9
INST_CMDLINE, // $CMDLINE
INST_INSTDIR, // $INSTDIR
INST_OUTDIR, // $OUTDIR
INST_EXEDIR, // $EXEDIR
INST_LANG, // $LANGUAGE
__INST_LAST
};
extern unsigned int g_stringsize;
extern stack_t **g_stacktop;
extern LPTSTR g_variables;
void NSISCALL pushstring(LPCTSTR str);
void NSISCALL pushintptr(INT_PTR value);
#define pushint(v) pushintptr((INT_PTR)(v))
int NSISCALL popstring(LPTSTR str); // 0 on success, 1 on empty stack
int NSISCALL popstringn(LPTSTR str, int maxlen); // with length limit, pass 0 for g_stringsize
INT_PTR NSISCALL popintptr();
#define popint() ( (int) popintptr() )
int NSISCALL popint_or(); // with support for or'ing (2|4|8)
INT_PTR NSISCALL nsishelper_str_to_ptr(LPCTSTR s);
#define myatoi(s) ( (int) nsishelper_str_to_ptr(s) ) // converts a string to an integer
unsigned int NSISCALL myatou(LPCTSTR s); // converts a string to an unsigned integer, decimal only
int NSISCALL myatoi_or(LPCTSTR s); // with support for or'ing (2|4|8)
LPTSTR NSISCALL getuservariable(const int varnum);
void NSISCALL setuservariable(const int varnum, LPCTSTR var);
#ifdef UNICODE
#define PopStringW(x) popstring(x)
#define PushStringW(x) pushstring(x)
#define SetUserVariableW(x,y) setuservariable(x,y)
int NSISCALL PopStringA(LPSTR ansiStr);
void NSISCALL PushStringA(LPCSTR ansiStr);
void NSISCALL GetUserVariableW(const int varnum, LPWSTR wideStr);
void NSISCALL GetUserVariableA(const int varnum, LPSTR ansiStr);
void NSISCALL SetUserVariableA(const int varnum, LPCSTR ansiStr);
#else
// ANSI defs
#define PopStringA(x) popstring(x)
#define PushStringA(x) pushstring(x)
#define SetUserVariableA(x,y) setuservariable(x,y)
int NSISCALL PopStringW(LPWSTR wideStr);
void NSISCALL PushStringW(LPWSTR wideStr);
void NSISCALL GetUserVariableW(const int varnum, LPWSTR wideStr);
void NSISCALL GetUserVariableA(const int varnum, LPSTR ansiStr);
void NSISCALL SetUserVariableW(const int varnum, LPCWSTR wideStr);
#endif
#ifdef __cplusplus
}
#endif
#endif//!___NSIS_PLUGIN__H___

View file

@ -1,28 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26403.7
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "signplugin", "signplugin.vcxproj", "{C6E4A1D7-ECBC-466E-9183-30727EF81533}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{C6E4A1D7-ECBC-466E-9183-30727EF81533}.Debug|x64.ActiveCfg = Debug|x64
{C6E4A1D7-ECBC-466E-9183-30727EF81533}.Debug|x64.Build.0 = Debug|x64
{C6E4A1D7-ECBC-466E-9183-30727EF81533}.Debug|x86.ActiveCfg = Debug|Win32
{C6E4A1D7-ECBC-466E-9183-30727EF81533}.Debug|x86.Build.0 = Debug|Win32
{C6E4A1D7-ECBC-466E-9183-30727EF81533}.Release|x64.ActiveCfg = Release|x64
{C6E4A1D7-ECBC-466E-9183-30727EF81533}.Release|x64.Build.0 = Release|x64
{C6E4A1D7-ECBC-466E-9183-30727EF81533}.Release|x86.ActiveCfg = Release|Win32
{C6E4A1D7-ECBC-466E-9183-30727EF81533}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View file

@ -1,166 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>15.0</VCProjectVersion>
<ProjectGuid>{C6E4A1D7-ECBC-466E-9183-30727EF81533}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>false</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>true</LinkIncremental>
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;SIGNPLUGIN_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization>
</ClCompile>
<Link>
<TargetMachine>MachineX86</TargetMachine>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<EntryPointSymbol>
</EntryPointSymbol>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;SIGNPLUGIN_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<ExceptionHandling>false</ExceptionHandling>
<BufferSecurityCheck>false</BufferSecurityCheck>
<Optimization>MinSpace</Optimization>
<OmitFramePointers>true</OmitFramePointers>
<FunctionLevelLinking>true</FunctionLevelLinking>
</ClCompile>
<Link>
<TargetMachine>MachineX86</TargetMachine>
<GenerateDebugInformation>false</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<EntryPointSymbol>DllMain</EntryPointSymbol>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="main.cpp" />
<ClCompile Include="tiny\c25519.c" />
<ClCompile Include="tiny\ed25519.c" />
<ClCompile Include="tiny\edsign.c" />
<ClCompile Include="tiny\f25519.c" />
<ClCompile Include="tiny\fprime.c" />
<ClCompile Include="tiny\morph25519.c" />
<ClCompile Include="tiny\sha512.c" />
<ClCompile Include="win32_crt_math.cpp" />
<ClCompile Include="win32_crt_memory.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="curve25519-donna-32bit.h" />
<ClInclude Include="curve25519-donna-64bit.h" />
<ClInclude Include="curve25519-donna-helpers.h" />
<ClInclude Include="curve25519-donna-sse2.h" />
<ClInclude Include="ed25519-donna-32bit-tables.h" />
<ClInclude Include="ed25519-donna-64bit-tables.h" />
<ClInclude Include="ed25519-donna-batchverify.h" />
<ClInclude Include="ed25519-donna-impl-base.h" />
<ClInclude Include="ed25519-donna-impl-sse2.h" />
<ClInclude Include="ed25519-donna-portable-identify.h" />
<ClInclude Include="ed25519-donna-portable.h" />
<ClInclude Include="ed25519-donna.h" />
<ClInclude Include="ed25519-hash-custom.h" />
<ClInclude Include="ed25519-hash.h" />
<ClInclude Include="ed25519-randombytes.h" />
<ClInclude Include="ed25519.h" />
<ClInclude Include="modm-donna-32bit.h" />
<ClInclude Include="modm-donna-64bit.h" />
<ClInclude Include="tiny\c25519.h" />
<ClInclude Include="tiny\ed25519.h" />
<ClInclude Include="tiny\edsign.h" />
<ClInclude Include="tiny\f25519.h" />
<ClInclude Include="tiny\fprime.h" />
<ClInclude Include="tiny\morph25519.h" />
<ClInclude Include="tiny\sha512.h" />
</ItemGroup>
<ItemGroup>
<Object Include="chkstk.obj">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
</Object>
</ItemGroup>
<ItemGroup>
<Library Include="nsis\pluginapi-x86-unicode.lib" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View file

@ -1,132 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="win32_crt_math.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="win32_crt_memory.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="tiny\c25519.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="tiny\ed25519.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="tiny\edsign.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="tiny\f25519.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="tiny\fprime.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="tiny\morph25519.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="tiny\sha512.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="curve25519-donna-32bit.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="curve25519-donna-64bit.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="curve25519-donna-helpers.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="curve25519-donna-sse2.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ed25519-donna-32bit-tables.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ed25519-donna-64bit-tables.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ed25519-donna-batchverify.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ed25519-donna-impl-base.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ed25519-donna-impl-sse2.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ed25519-donna-portable-identify.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ed25519-donna-portable.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ed25519-donna.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ed25519-hash-custom.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ed25519-hash.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ed25519-randombytes.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ed25519.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="modm-donna-32bit.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="modm-donna-64bit.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="tiny\c25519.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="tiny\ed25519.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="tiny\edsign.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="tiny\f25519.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="tiny\fprime.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="tiny\morph25519.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="tiny\sha512.h">
<Filter>Source Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Object Include="chkstk.obj" />
</ItemGroup>
<ItemGroup>
<Library Include="nsis\pluginapi-x86-unicode.lib" />
</ItemGroup>
</Project>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup />
</Project>

View file

@ -1,124 +0,0 @@
/* Curve25519 (Montgomery form)
* Daniel Beer <dlbeer@gmail.com>, 18 Apr 2014
*
* This file is in the public domain.
*/
#include "c25519.h"
const uint8_t c25519_base_x[F25519_SIZE] = {9};
/* Double an X-coordinate */
static void xc_double(uint8_t *x3, uint8_t *z3,
const uint8_t *x1, const uint8_t *z1)
{
/* Explicit formulas database: dbl-1987-m
*
* source 1987 Montgomery "Speeding the Pollard and elliptic
* curve methods of factorization", page 261, fourth display
* compute X3 = (X1^2-Z1^2)^2
* compute Z3 = 4 X1 Z1 (X1^2 + a X1 Z1 + Z1^2)
*/
uint8_t x1sq[F25519_SIZE];
uint8_t z1sq[F25519_SIZE];
uint8_t x1z1[F25519_SIZE];
uint8_t a[F25519_SIZE];
f25519_mul__distinct(x1sq, x1, x1);
f25519_mul__distinct(z1sq, z1, z1);
f25519_mul__distinct(x1z1, x1, z1);
f25519_sub(a, x1sq, z1sq);
f25519_mul__distinct(x3, a, a);
f25519_mul_c(a, x1z1, 486662);
f25519_add(a, x1sq, a);
f25519_add(a, z1sq, a);
f25519_mul__distinct(x1sq, x1z1, a);
f25519_mul_c(z3, x1sq, 4);
}
/* Differential addition */
static void xc_diffadd(uint8_t *x5, uint8_t *z5,
const uint8_t *x1, const uint8_t *z1,
const uint8_t *x2, const uint8_t *z2,
const uint8_t *x3, const uint8_t *z3)
{
/* Explicit formulas database: dbl-1987-m3
*
* source 1987 Montgomery "Speeding the Pollard and elliptic curve
* methods of factorization", page 261, fifth display, plus
* common-subexpression elimination
* compute A = X2+Z2
* compute B = X2-Z2
* compute C = X3+Z3
* compute D = X3-Z3
* compute DA = D A
* compute CB = C B
* compute X5 = Z1(DA+CB)^2
* compute Z5 = X1(DA-CB)^2
*/
uint8_t da[F25519_SIZE];
uint8_t cb[F25519_SIZE];
uint8_t a[F25519_SIZE];
uint8_t b[F25519_SIZE];
f25519_add(a, x2, z2);
f25519_sub(b, x3, z3); /* D */
f25519_mul__distinct(da, a, b);
f25519_sub(b, x2, z2);
f25519_add(a, x3, z3); /* C */
f25519_mul__distinct(cb, a, b);
f25519_add(a, da, cb);
f25519_mul__distinct(b, a, a);
f25519_mul__distinct(x5, z1, b);
f25519_sub(a, da, cb);
f25519_mul__distinct(b, a, a);
f25519_mul__distinct(z5, x1, b);
}
void c25519_smult(uint8_t *result, const uint8_t *q, const uint8_t *e)
{
/* Current point: P_m */
uint8_t xm[F25519_SIZE];
uint8_t zm[F25519_SIZE] = {1};
/* Predecessor: P_(m-1) */
uint8_t xm1[F25519_SIZE] = {1};
uint8_t zm1[F25519_SIZE] = {0};
int i;
/* Note: bit 254 is assumed to be 1 */
f25519_copy(xm, q);
for (i = 253; i >= 0; i--) {
const int bit = (e[i >> 3] >> (i & 7)) & 1;
uint8_t xms[F25519_SIZE];
uint8_t zms[F25519_SIZE];
/* From P_m and P_(m-1), compute P_(2m) and P_(2m-1) */
xc_diffadd(xm1, zm1, q, f25519_one, xm, zm, xm1, zm1);
xc_double(xm, zm, xm, zm);
/* Compute P_(2m+1) */
xc_diffadd(xms, zms, xm1, zm1, xm, zm, q, f25519_one);
/* Select:
* bit = 1 --> (P_(2m+1), P_(2m))
* bit = 0 --> (P_(2m), P_(2m-1))
*/
f25519_select(xm1, xm1, xm, bit);
f25519_select(zm1, zm1, zm, bit);
f25519_select(xm, xm, xms, bit);
f25519_select(zm, zm, zms, bit);
}
/* Freeze out of projective coordinates */
f25519_inv__distinct(zm1, zm);
f25519_mul__distinct(result, zm1, xm);
f25519_normalize(result);
}

View file

@ -1,48 +0,0 @@
/* Curve25519 (Montgomery form)
* Daniel Beer <dlbeer@gmail.com>, 18 Apr 2014
*
* This file is in the public domain.
*/
#ifndef C25519_H_
#define C25519_H_
#include <stdint.h>
#include "f25519.h"
/* Curve25519 has the equation over F(p = 2^255-19):
*
* y^2 = x^3 + 486662x^2 + x
*
* 486662 = 4A+2, where A = 121665. This is a Montgomery curve.
*
* For more information, see:
*
* Bernstein, D.J. (2006) "Curve25519: New Diffie-Hellman speed
* records". Document ID: 4230efdfa673480fc079449d90f322c0.
*/
/* This is the site of a Curve25519 exponent (private key) */
#define C25519_EXPONENT_SIZE 32
/* Having generated 32 random bytes, you should call this function to
* finalize the generated key.
*/
static inline void c25519_prepare(uint8_t *key)
{
key[0] &= 0xf8;
key[31] &= 0x7f;
key[31] |= 0x40;
}
/* X-coordinate of the base point */
extern const uint8_t c25519_base_x[F25519_SIZE];
/* X-coordinate scalar multiply: given the X-coordinate of q, return the
* X-coordinate of e*q.
*
* result and q are field elements. e is an exponent.
*/
void c25519_smult(uint8_t *result, const uint8_t *q, const uint8_t *e);
#endif

View file

@ -1,320 +0,0 @@
/* Edwards curve operations
* Daniel Beer <dlbeer@gmail.com>, 9 Jan 2014
*
* This file is in the public domain.
*/
#include "ed25519.h"
/* Base point is (numbers wrapped):
*
* x = 151122213495354007725011514095885315114
* 54012693041857206046113283949847762202
* y = 463168356949264781694283940034751631413
* 07993866256225615783033603165251855960
*
* y is derived by transforming the original Montgomery base (u=9). x
* is the corresponding positive coordinate for the new curve equation.
* t is x*y.
*/
const struct ed25519_pt ed25519_base = {
.x = {
0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9,
0xb2, 0xa7, 0x25, 0x95, 0x60, 0xc7, 0x2c, 0x69,
0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0,
0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21
},
.y = {
0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66
},
.t = {
0xa3, 0xdd, 0xb7, 0xa5, 0xb3, 0x8a, 0xde, 0x6d,
0xf5, 0x52, 0x51, 0x77, 0x80, 0x9f, 0xf0, 0x20,
0x7d, 0xe3, 0xab, 0x64, 0x8e, 0x4e, 0xea, 0x66,
0x65, 0x76, 0x8b, 0xd7, 0x0f, 0x5f, 0x87, 0x67
},
.z = {1, 0}
};
const struct ed25519_pt ed25519_neutral = {
.x = {0},
.y = {1, 0},
.t = {0},
.z = {1, 0}
};
/* Conversion to and from projective coordinates */
void ed25519_project(struct ed25519_pt *p,
const uint8_t *x, const uint8_t *y)
{
f25519_copy(p->x, x);
f25519_copy(p->y, y);
f25519_load(p->z, 1);
f25519_mul__distinct(p->t, x, y);
}
void ed25519_unproject(uint8_t *x, uint8_t *y,
const struct ed25519_pt *p)
{
uint8_t z1[F25519_SIZE];
f25519_inv__distinct(z1, p->z);
f25519_mul__distinct(x, p->x, z1);
f25519_mul__distinct(y, p->y, z1);
f25519_normalize(x);
f25519_normalize(y);
}
/* Compress/uncompress points. We compress points by storing the x
* coordinate and the parity of the y coordinate.
*
* Rearranging the curve equation, we obtain explicit formulae for the
* coordinates:
*
* x = sqrt((y^2-1) / (1+dy^2))
* y = sqrt((x^2+1) / (1-dx^2))
*
* Where d = (-121665/121666), or:
*
* d = 370957059346694393431380835087545651895
* 42113879843219016388785533085940283555
*/
static const uint8_t ed25519_d[F25519_SIZE] = {
0xa3, 0x78, 0x59, 0x13, 0xca, 0x4d, 0xeb, 0x75,
0xab, 0xd8, 0x41, 0x41, 0x4d, 0x0a, 0x70, 0x00,
0x98, 0xe8, 0x79, 0x77, 0x79, 0x40, 0xc7, 0x8c,
0x73, 0xfe, 0x6f, 0x2b, 0xee, 0x6c, 0x03, 0x52
};
void ed25519_pack(uint8_t *c, const uint8_t *x, const uint8_t *y)
{
uint8_t tmp[F25519_SIZE];
uint8_t parity;
f25519_copy(tmp, x);
f25519_normalize(tmp);
parity = (tmp[0] & 1) << 7;
f25519_copy(c, y);
f25519_normalize(c);
c[31] |= parity;
}
uint8_t ed25519_try_unpack(uint8_t *x, uint8_t *y, const uint8_t *comp)
{
const int parity = comp[31] >> 7;
uint8_t a[F25519_SIZE];
uint8_t b[F25519_SIZE];
uint8_t c[F25519_SIZE];
/* Unpack y */
f25519_copy(y, comp);
y[31] &= 127;
/* Compute c = y^2 */
f25519_mul__distinct(c, y, y);
/* Compute b = (1+dy^2)^-1 */
f25519_mul__distinct(b, c, ed25519_d);
f25519_add(a, b, f25519_one);
f25519_inv__distinct(b, a);
/* Compute a = y^2-1 */
f25519_sub(a, c, f25519_one);
/* Compute c = a*b = (y^2-1)/(1-dy^2) */
f25519_mul__distinct(c, a, b);
/* Compute a, b = +/-sqrt(c), if c is square */
f25519_sqrt(a, c);
f25519_neg(b, a);
/* Select one of them, based on the compressed parity bit */
f25519_select(x, a, b, (a[0] ^ parity) & 1);
/* Verify that x^2 = c */
f25519_mul__distinct(a, x, x);
f25519_normalize(a);
f25519_normalize(c);
return f25519_eq(a, c);
}
/* k = 2d */
static const uint8_t ed25519_k[F25519_SIZE] = {
0x59, 0xf1, 0xb2, 0x26, 0x94, 0x9b, 0xd6, 0xeb,
0x56, 0xb1, 0x83, 0x82, 0x9a, 0x14, 0xe0, 0x00,
0x30, 0xd1, 0xf3, 0xee, 0xf2, 0x80, 0x8e, 0x19,
0xe7, 0xfc, 0xdf, 0x56, 0xdc, 0xd9, 0x06, 0x24
};
void ed25519_add(struct ed25519_pt *r,
const struct ed25519_pt *p1, const struct ed25519_pt *p2)
{
/* Explicit formulas database: add-2008-hwcd-3
*
* source 2008 Hisil--Wong--Carter--Dawson,
* http://eprint.iacr.org/2008/522, Section 3.1
* appliesto extended-1
* parameter k
* assume k = 2 d
* compute A = (Y1-X1)(Y2-X2)
* compute B = (Y1+X1)(Y2+X2)
* compute C = T1 k T2
* compute D = Z1 2 Z2
* compute E = B - A
* compute F = D - C
* compute G = D + C
* compute H = B + A
* compute X3 = E F
* compute Y3 = G H
* compute T3 = E H
* compute Z3 = F G
*/
uint8_t a[F25519_SIZE];
uint8_t b[F25519_SIZE];
uint8_t c[F25519_SIZE];
uint8_t d[F25519_SIZE];
uint8_t e[F25519_SIZE];
uint8_t f[F25519_SIZE];
uint8_t g[F25519_SIZE];
uint8_t h[F25519_SIZE];
/* A = (Y1-X1)(Y2-X2) */
f25519_sub(c, p1->y, p1->x);
f25519_sub(d, p2->y, p2->x);
f25519_mul__distinct(a, c, d);
/* B = (Y1+X1)(Y2+X2) */
f25519_add(c, p1->y, p1->x);
f25519_add(d, p2->y, p2->x);
f25519_mul__distinct(b, c, d);
/* C = T1 k T2 */
f25519_mul__distinct(d, p1->t, p2->t);
f25519_mul__distinct(c, d, ed25519_k);
/* D = Z1 2 Z2 */
f25519_mul__distinct(d, p1->z, p2->z);
f25519_add(d, d, d);
/* E = B - A */
f25519_sub(e, b, a);
/* F = D - C */
f25519_sub(f, d, c);
/* G = D + C */
f25519_add(g, d, c);
/* H = B + A */
f25519_add(h, b, a);
/* X3 = E F */
f25519_mul__distinct(r->x, e, f);
/* Y3 = G H */
f25519_mul__distinct(r->y, g, h);
/* T3 = E H */
f25519_mul__distinct(r->t, e, h);
/* Z3 = F G */
f25519_mul__distinct(r->z, f, g);
}
void ed25519_double(struct ed25519_pt *r, const struct ed25519_pt *p)
{
/* Explicit formulas database: dbl-2008-hwcd
*
* source 2008 Hisil--Wong--Carter--Dawson,
* http://eprint.iacr.org/2008/522, Section 3.3
* compute A = X1^2
* compute B = Y1^2
* compute C = 2 Z1^2
* compute D = a A
* compute E = (X1+Y1)^2-A-B
* compute G = D + B
* compute F = G - C
* compute H = D - B
* compute X3 = E F
* compute Y3 = G H
* compute T3 = E H
* compute Z3 = F G
*/
uint8_t a[F25519_SIZE];
uint8_t b[F25519_SIZE];
uint8_t c[F25519_SIZE];
uint8_t e[F25519_SIZE];
uint8_t f[F25519_SIZE];
uint8_t g[F25519_SIZE];
uint8_t h[F25519_SIZE];
/* A = X1^2 */
f25519_mul__distinct(a, p->x, p->x);
/* B = Y1^2 */
f25519_mul__distinct(b, p->y, p->y);
/* C = 2 Z1^2 */
f25519_mul__distinct(c, p->z, p->z);
f25519_add(c, c, c);
/* D = a A (alter sign) */
/* E = (X1+Y1)^2-A-B */
f25519_add(f, p->x, p->y);
f25519_mul__distinct(e, f, f);
f25519_sub(e, e, a);
f25519_sub(e, e, b);
/* G = D + B */
f25519_sub(g, b, a);
/* F = G - C */
f25519_sub(f, g, c);
/* H = D - B */
f25519_neg(h, b);
f25519_sub(h, h, a);
/* X3 = E F */
f25519_mul__distinct(r->x, e, f);
/* Y3 = G H */
f25519_mul__distinct(r->y, g, h);
/* T3 = E H */
f25519_mul__distinct(r->t, e, h);
/* Z3 = F G */
f25519_mul__distinct(r->z, f, g);
}
void ed25519_smult(struct ed25519_pt *r_out, const struct ed25519_pt *p,
const uint8_t *e)
{
struct ed25519_pt r;
int i;
ed25519_copy(&r, &ed25519_neutral);
for (i = 255; i >= 0; i--) {
const uint8_t bit = (e[i >> 3] >> (i & 7)) & 1;
struct ed25519_pt s;
ed25519_double(&r, &r);
ed25519_add(&s, &r, p);
f25519_select(r.x, r.x, s.x, bit);
f25519_select(r.y, r.y, s.y, bit);
f25519_select(r.z, r.z, s.z, bit);
f25519_select(r.t, r.t, s.t, bit);
}
ed25519_copy(r_out, &r);
}

View file

@ -1,82 +0,0 @@
/* Edwards curve operations
* Daniel Beer <dlbeer@gmail.com>, 9 Jan 2014
*
* This file is in the public domain.
*/
#ifndef ED25519_H_
#define ED25519_H_
#include "f25519.h"
/* This is not the Ed25519 signature system. Rather, we're implementing
* basic operations on the twisted Edwards curve over (Z mod 2^255-19):
*
* -x^2 + y^2 = 1 - (121665/121666)x^2y^2
*
* With the positive-x base point y = 4/5.
*
* These functions will not leak secret data through timing.
*
* For more information, see:
*
* Bernstein, D.J. & Lange, T. (2007) "Faster addition and doubling on
* elliptic curves". Document ID: 95616567a6ba20f575c5f25e7cebaf83.
*
* Hisil, H. & Wong, K K. & Carter, G. & Dawson, E. (2008) "Twisted
* Edwards curves revisited". Advances in Cryptology, ASIACRYPT 2008,
* Vol. 5350, pp. 326-343.
*/
/* Projective coordinates */
struct ed25519_pt {
uint8_t x[F25519_SIZE];
uint8_t y[F25519_SIZE];
uint8_t t[F25519_SIZE];
uint8_t z[F25519_SIZE];
};
extern const struct ed25519_pt ed25519_base;
extern const struct ed25519_pt ed25519_neutral;
/* Convert between projective and affine coordinates (x/y in F25519) */
void ed25519_project(struct ed25519_pt *p,
const uint8_t *x, const uint8_t *y);
void ed25519_unproject(uint8_t *x, uint8_t *y,
const struct ed25519_pt *p);
/* Compress/uncompress points. try_unpack() will check that the
* compressed point is on the curve, returning 1 if the unpacked point
* is valid, and 0 otherwise.
*/
#define ED25519_PACK_SIZE F25519_SIZE
void ed25519_pack(uint8_t *c, const uint8_t *x, const uint8_t *y);
uint8_t ed25519_try_unpack(uint8_t *x, uint8_t *y, const uint8_t *c);
/* Add, double and scalar multiply */
#define ED25519_EXPONENT_SIZE 32
/* Prepare an exponent by clamping appropriate bits */
static inline void ed25519_prepare(uint8_t *e)
{
e[0] &= 0xf8;
e[31] &= 0x7f;
e[31] |= 0x40;
}
/* Order of the group generated by the base point */
static inline void ed25519_copy(struct ed25519_pt *dst,
const struct ed25519_pt *src)
{
memcpy(dst, src, sizeof(*dst));
}
void ed25519_add(struct ed25519_pt *r,
const struct ed25519_pt *a, const struct ed25519_pt *b);
void ed25519_double(struct ed25519_pt *r, const struct ed25519_pt *a);
void ed25519_smult(struct ed25519_pt *r, const struct ed25519_pt *a,
const uint8_t *e);
#endif

View file

@ -1,168 +0,0 @@
/* Edwards curve signature system
* Daniel Beer <dlbeer@gmail.com>, 22 Apr 2014
*
* This file is in the public domain.
*/
#include "ed25519.h"
#include "sha512.h"
#include "fprime.h"
#include "edsign.h"
#define EXPANDED_SIZE 64
static const uint8_t ed25519_order[FPRIME_SIZE] = {
0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58,
0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10
};
static void expand_key(uint8_t *expanded, const uint8_t *secret)
{
struct sha512_state s;
sha512_init(&s);
sha512_final(&s, secret, EDSIGN_SECRET_KEY_SIZE);
sha512_get(&s, expanded, 0, EXPANDED_SIZE);
ed25519_prepare(expanded);
}
static uint8_t upp(struct ed25519_pt *p, const uint8_t *packed)
{
uint8_t x[F25519_SIZE];
uint8_t y[F25519_SIZE];
uint8_t ok = ed25519_try_unpack(x, y, packed);
ed25519_project(p, x, y);
return ok;
}
static void pp(uint8_t *packed, const struct ed25519_pt *p)
{
uint8_t x[F25519_SIZE];
uint8_t y[F25519_SIZE];
ed25519_unproject(x, y, p);
ed25519_pack(packed, x, y);
}
static void sm_pack(uint8_t *r, const uint8_t *k)
{
struct ed25519_pt p;
ed25519_smult(&p, &ed25519_base, k);
pp(r, &p);
}
void edsign_sec_to_pub(uint8_t *pub, const uint8_t *secret)
{
uint8_t expanded[EXPANDED_SIZE];
expand_key(expanded, secret);
sm_pack(pub, expanded);
}
static void hash_with_prefix(uint8_t *out_fp,
uint8_t *init_block, unsigned int prefix_size,
const uint8_t *message, size_t len)
{
struct sha512_state s;
sha512_init(&s);
if (len < SHA512_BLOCK_SIZE && len + prefix_size < SHA512_BLOCK_SIZE) {
memcpy(init_block + prefix_size, message, len);
sha512_final(&s, init_block, len + prefix_size);
} else {
size_t i;
memcpy(init_block + prefix_size, message,
SHA512_BLOCK_SIZE - prefix_size);
sha512_block(&s, init_block);
for (i = SHA512_BLOCK_SIZE - prefix_size;
i + SHA512_BLOCK_SIZE <= len;
i += SHA512_BLOCK_SIZE)
sha512_block(&s, message + i);
sha512_final(&s, message + i, len + prefix_size);
}
sha512_get(&s, init_block, 0, SHA512_HASH_SIZE);
fprime_from_bytes(out_fp, init_block, SHA512_HASH_SIZE, ed25519_order);
}
static void generate_k(uint8_t *k, const uint8_t *kgen_key,
const uint8_t *message, size_t len)
{
uint8_t block[SHA512_BLOCK_SIZE];
memcpy(block, kgen_key, 32);
hash_with_prefix(k, block, 32, message, len);
}
static void hash_message(uint8_t *z, const uint8_t *r, const uint8_t *a,
const uint8_t *m, size_t len)
{
uint8_t block[SHA512_BLOCK_SIZE];
memcpy(block, r, 32);
memcpy(block + 32, a, 32);
hash_with_prefix(z, block, 64, m, len);
}
void edsign_sign(uint8_t *signature, const uint8_t *pub,
const uint8_t *secret,
const uint8_t *message, size_t len)
{
uint8_t expanded[EXPANDED_SIZE];
uint8_t e[FPRIME_SIZE];
uint8_t s[FPRIME_SIZE];
uint8_t k[FPRIME_SIZE];
uint8_t z[FPRIME_SIZE];
expand_key(expanded, secret);
/* Generate k and R = kB */
generate_k(k, expanded + 32, message, len);
sm_pack(signature, k);
/* Compute z = H(R, A, M) */
hash_message(z, signature, pub, message, len);
/* Obtain e */
fprime_from_bytes(e, expanded, 32, ed25519_order);
/* Compute s = ze + k */
fprime_mul(s, z, e, ed25519_order);
fprime_add(s, k, ed25519_order);
memcpy(signature + 32, s, 32);
}
uint8_t edsign_verify(const uint8_t *signature, const uint8_t *pub,
const uint8_t *message, size_t len)
{
struct ed25519_pt p;
struct ed25519_pt q;
uint8_t lhs[F25519_SIZE];
uint8_t rhs[F25519_SIZE];
uint8_t z[FPRIME_SIZE];
uint8_t ok = 1;
/* Compute z = H(R, A, M) */
hash_message(z, signature, pub, message, len);
/* sB = (ze + k)B = ... */
sm_pack(lhs, signature + 32);
/* ... = zA + R */
ok &= upp(&p, pub);
ed25519_smult(&p, &p, z);
ok &= upp(&q, signature);
ed25519_add(&p, &p, &q);
pp(rhs, &p);
/* Equal? */
return ok & f25519_eq(lhs, rhs);
}

View file

@ -1,51 +0,0 @@
/* Edwards curve signature system
* Daniel Beer <dlbeer@gmail.com>, 22 Apr 2014
*
* This file is in the public domain.
*/
#ifndef EDSIGN_H_
#define EDSIGN_H_
#include <stdint.h>
#include <stddef.h>
/* This is the Ed25519 signature system, as described in:
*
* Daniel J. Bernstein, Niels Duif, Tanja Lange, Peter Schwabe, Bo-Yin
* Yang. High-speed high-security signatures. Journal of Cryptographic
* Engineering 2 (2012), 77-89. Document ID:
* a1a62a2f76d23f65d622484ddd09caf8. URL:
* http://cr.yp.to/papers.html#ed25519. Date: 2011.09.26.
*
* The format and calculation of signatures is compatible with the
* Ed25519 implementation in SUPERCOP. Note, however, that our secret
* keys are half the size: we don't store a copy of the public key in
* the secret key (we generate it on demand).
*/
/* Any string of 32 random bytes is a valid secret key. There is no
* clamping of bits, because we don't use the key directly as an
* exponent (the exponent is derived from part of a key expansion).
*/
#define EDSIGN_SECRET_KEY_SIZE 32
/* Given a secret key, produce the public key (a packed Edwards-curve
* point).
*/
#define EDSIGN_PUBLIC_KEY_SIZE 32
void edsign_sec_to_pub(uint8_t *pub, const uint8_t *secret);
/* Produce a signature for a message. */
#define EDSIGN_SIGNATURE_SIZE 64
void edsign_sign(uint8_t *signature, const uint8_t *pub,
const uint8_t *secret,
const uint8_t *message, size_t len);
/* Verify a message signature. Returns non-zero if ok. */
uint8_t edsign_verify(const uint8_t *signature, const uint8_t *pub,
const uint8_t *message, size_t len);
#endif

View file

@ -1,324 +0,0 @@
/* Arithmetic mod p = 2^255-19
* Daniel Beer <dlbeer@gmail.com>, 5 Jan 2014
*
* This file is in the public domain.
*/
#include "f25519.h"
const uint8_t f25519_zero[F25519_SIZE] = {0};
const uint8_t f25519_one[F25519_SIZE] = {1};
void f25519_load(uint8_t *x, uint32_t c)
{
unsigned int i;
for (i = 0; i < sizeof(c); i++) {
x[i] = c;
c >>= 8;
}
for (; i < F25519_SIZE; i++)
x[i] = 0;
}
void f25519_normalize(uint8_t *x)
{
uint8_t minusp[F25519_SIZE];
uint16_t c;
int i;
/* Reduce using 2^255 = 19 mod p */
c = (x[31] >> 7) * 19;
x[31] &= 127;
for (i = 0; i < F25519_SIZE; i++) {
c += x[i];
x[i] = c;
c >>= 8;
}
/* The number is now less than 2^255 + 18, and therefore less than
* 2p. Try subtracting p, and conditionally load the subtracted
* value if underflow did not occur.
*/
c = 19;
for (i = 0; i + 1 < F25519_SIZE; i++) {
c += x[i];
minusp[i] = c;
c >>= 8;
}
c += ((uint16_t)x[i]) - 128;
minusp[31] = c;
/* Load x-p if no underflow */
f25519_select(x, minusp, x, (c >> 15) & 1);
}
uint8_t f25519_eq(const uint8_t *x, const uint8_t *y)
{
uint8_t sum = 0;
int i;
for (i = 0; i < F25519_SIZE; i++)
sum |= x[i] ^ y[i];
sum |= (sum >> 4);
sum |= (sum >> 2);
sum |= (sum >> 1);
return (sum ^ 1) & 1;
}
void f25519_select(uint8_t *dst,
const uint8_t *zero, const uint8_t *one,
uint8_t condition)
{
const uint8_t mask = -condition;
int i;
for (i = 0; i < F25519_SIZE; i++)
dst[i] = zero[i] ^ (mask & (one[i] ^ zero[i]));
}
void f25519_add(uint8_t *r, const uint8_t *a, const uint8_t *b)
{
uint16_t c = 0;
int i;
/* Add */
for (i = 0; i < F25519_SIZE; i++) {
c >>= 8;
c += ((uint16_t)a[i]) + ((uint16_t)b[i]);
r[i] = c;
}
/* Reduce with 2^255 = 19 mod p */
r[31] &= 127;
c = (c >> 7) * 19;
for (i = 0; i < F25519_SIZE; i++) {
c += r[i];
r[i] = c;
c >>= 8;
}
}
void f25519_sub(uint8_t *r, const uint8_t *a, const uint8_t *b)
{
uint32_t c = 0;
int i;
/* Calculate a + 2p - b, to avoid underflow */
c = 218;
for (i = 0; i + 1 < F25519_SIZE; i++) {
c += 65280 + ((uint32_t)a[i]) - ((uint32_t)b[i]);
r[i] = c;
c >>= 8;
}
c += ((uint32_t)a[31]) - ((uint32_t)b[31]);
r[31] = c & 127;
c = (c >> 7) * 19;
for (i = 0; i < F25519_SIZE; i++) {
c += r[i];
r[i] = c;
c >>= 8;
}
}
void f25519_neg(uint8_t *r, const uint8_t *a)
{
uint32_t c = 0;
int i;
/* Calculate 2p - a, to avoid underflow */
c = 218;
for (i = 0; i + 1 < F25519_SIZE; i++) {
c += 65280 - ((uint32_t)a[i]);
r[i] = c;
c >>= 8;
}
c -= ((uint32_t)a[31]);
r[31] = c & 127;
c = (c >> 7) * 19;
for (i = 0; i < F25519_SIZE; i++) {
c += r[i];
r[i] = c;
c >>= 8;
}
}
void f25519_mul__distinct(uint8_t *r, const uint8_t *a, const uint8_t *b)
{
uint32_t c = 0;
int i;
for (i = 0; i < F25519_SIZE; i++) {
int j;
c >>= 8;
for (j = 0; j <= i; j++)
c += ((uint32_t)a[j]) * ((uint32_t)b[i - j]);
for (; j < F25519_SIZE; j++)
c += ((uint32_t)a[j]) *
((uint32_t)b[i + F25519_SIZE - j]) * 38;
r[i] = c;
}
r[31] &= 127;
c = (c >> 7) * 19;
for (i = 0; i < F25519_SIZE; i++) {
c += r[i];
r[i] = c;
c >>= 8;
}
}
void f25519_mul(uint8_t *r, const uint8_t *a, const uint8_t *b)
{
uint8_t tmp[F25519_SIZE];
f25519_mul__distinct(tmp, a, b);
f25519_copy(r, tmp);
}
void f25519_mul_c(uint8_t *r, const uint8_t *a, uint32_t b)
{
uint32_t c = 0;
int i;
for (i = 0; i < F25519_SIZE; i++) {
c >>= 8;
c += b * ((uint32_t)a[i]);
r[i] = c;
}
r[31] &= 127;
c >>= 7;
c *= 19;
for (i = 0; i < F25519_SIZE; i++) {
c += r[i];
r[i] = c;
c >>= 8;
}
}
void f25519_inv__distinct(uint8_t *r, const uint8_t *x)
{
uint8_t s[F25519_SIZE];
int i;
/* This is a prime field, so by Fermat's little theorem:
*
* x^(p-1) = 1 mod p
*
* Therefore, raise to (p-2) = 2^255-21 to get a multiplicative
* inverse.
*
* This is a 255-bit binary number with the digits:
*
* 11111111... 01011
*
* We compute the result by the usual binary chain, but
* alternate between keeping the accumulator in r and s, so as
* to avoid copying temporaries.
*/
/* 1 1 */
f25519_mul__distinct(s, x, x);
f25519_mul__distinct(r, s, x);
/* 1 x 248 */
for (i = 0; i < 248; i++) {
f25519_mul__distinct(s, r, r);
f25519_mul__distinct(r, s, x);
}
/* 0 */
f25519_mul__distinct(s, r, r);
/* 1 */
f25519_mul__distinct(r, s, s);
f25519_mul__distinct(s, r, x);
/* 0 */
f25519_mul__distinct(r, s, s);
/* 1 */
f25519_mul__distinct(s, r, r);
f25519_mul__distinct(r, s, x);
/* 1 */
f25519_mul__distinct(s, r, r);
f25519_mul__distinct(r, s, x);
}
void f25519_inv(uint8_t *r, const uint8_t *x)
{
uint8_t tmp[F25519_SIZE];
f25519_inv__distinct(tmp, x);
f25519_copy(r, tmp);
}
/* Raise x to the power of (p-5)/8 = 2^252-3, using s for temporary
* storage.
*/
static void exp2523(uint8_t *r, const uint8_t *x, uint8_t *s)
{
int i;
/* This number is a 252-bit number with the binary expansion:
*
* 111111... 01
*/
/* 1 1 */
f25519_mul__distinct(r, x, x);
f25519_mul__distinct(s, r, x);
/* 1 x 248 */
for (i = 0; i < 248; i++) {
f25519_mul__distinct(r, s, s);
f25519_mul__distinct(s, r, x);
}
/* 0 */
f25519_mul__distinct(r, s, s);
/* 1 */
f25519_mul__distinct(s, r, r);
f25519_mul__distinct(r, s, x);
}
void f25519_sqrt(uint8_t *r, const uint8_t *a)
{
uint8_t v[F25519_SIZE];
uint8_t i[F25519_SIZE];
uint8_t x[F25519_SIZE];
uint8_t y[F25519_SIZE];
/* v = (2a)^((p-5)/8) [x = 2a] */
f25519_mul_c(x, a, 2);
exp2523(v, x, y);
/* i = 2av^2 - 1 */
f25519_mul__distinct(y, v, v);
f25519_mul__distinct(i, x, y);
f25519_load(y, 1);
f25519_sub(i, i, y);
/* r = avi */
f25519_mul__distinct(x, v, a);
f25519_mul__distinct(r, x, i);
}

View file

@ -1,92 +0,0 @@
/* Arithmetic mod p = 2^255-19
* Daniel Beer <dlbeer@gmail.com>, 8 Jan 2014
*
* This file is in the public domain.
*/
#ifndef F25519_H_
#define F25519_H_
#include <stdint.h>
#include <string.h>
/* Field elements are represented as little-endian byte strings. All
* operations have timings which are independent of input data, so they
* can be safely used for cryptography.
*
* Computation is performed on un-normalized elements. These are byte
* strings which fall into the range 0 <= x < 2p. Use f25519_normalize()
* to convert to a value 0 <= x < p.
*
* Elements received from the outside may greater even than 2p.
* f25519_normalize() will correctly deal with these numbers too.
*/
#define F25519_SIZE 32
/* Identity constants */
extern const uint8_t f25519_zero[F25519_SIZE];
extern const uint8_t f25519_one[F25519_SIZE];
/* Load a small constant */
void f25519_load(uint8_t *x, uint32_t c);
/* Copy two points */
static inline void f25519_copy(uint8_t *x, const uint8_t *a)
{
memcpy(x, a, F25519_SIZE);
}
/* Normalize a field point x < 2*p by subtracting p if necessary */
void f25519_normalize(uint8_t *x);
/* Compare two field points in constant time. Return one if equal, zero
* otherwise. This should be performed only on normalized values.
*/
uint8_t f25519_eq(const uint8_t *x, const uint8_t *y);
/* Conditional copy. If condition == 0, then zero is copied to dst. If
* condition == 1, then one is copied to dst. Any other value results in
* undefined behaviour.
*/
void f25519_select(uint8_t *dst,
const uint8_t *zero, const uint8_t *one,
uint8_t condition);
/* Add/subtract two field points. The three pointers are not required to
* be distinct.
*/
void f25519_add(uint8_t *r, const uint8_t *a, const uint8_t *b);
void f25519_sub(uint8_t *r, const uint8_t *a, const uint8_t *b);
/* Unary negation */
void f25519_neg(uint8_t *r, const uint8_t *a);
/* Multiply two field points. The __distinct variant is used when r is
* known to be in a different location to a and b.
*/
void f25519_mul(uint8_t *r, const uint8_t *a, const uint8_t *b);
void f25519_mul__distinct(uint8_t *r, const uint8_t *a, const uint8_t *b);
/* Multiply a point by a small constant. The two pointers are not
* required to be distinct.
*
* The constant must be less than 2^24.
*/
void f25519_mul_c(uint8_t *r, const uint8_t *a, uint32_t b);
/* Take the reciprocal of a field point. The __distinct variant is used
* when r is known to be in a different location to x.
*/
void f25519_inv(uint8_t *r, const uint8_t *x);
void f25519_inv__distinct(uint8_t *r, const uint8_t *x);
/* Compute one of the square roots of the field element, if the element
* is square. The other square is -r.
*
* If the input is not square, the returned value is a valid field
* element, but not the correct answer. If you don't already know that
* your element is square, you should square the return value and test.
*/
void f25519_sqrt(uint8_t *r, const uint8_t *x);
#endif

View file

@ -1,215 +0,0 @@
/* Arithmetic in prime fields
* Daniel Beer <dlbeer@gmail.com>, 10 Jan 2014
*
* This file is in the public domain.
*/
#include "fprime.h"
const uint8_t fprime_zero[FPRIME_SIZE] = {0};
const uint8_t fprime_one[FPRIME_SIZE] = {1};
static void raw_add(uint8_t *x, const uint8_t *p)
{
uint16_t c = 0;
int i;
for (i = 0; i < FPRIME_SIZE; i++) {
c += ((uint16_t)x[i]) + ((uint16_t)p[i]);
x[i] = c;
c >>= 8;
}
}
static void raw_try_sub(uint8_t *x, const uint8_t *p)
{
uint8_t minusp[FPRIME_SIZE];
uint16_t c = 0;
int i;
for (i = 0; i < FPRIME_SIZE; i++) {
c = ((uint16_t)x[i]) - ((uint16_t)p[i]) - c;
minusp[i] = c;
c = (c >> 8) & 1;
}
fprime_select(x, minusp, x, c);
}
/* Warning: this function is variable-time */
static int prime_msb(const uint8_t *p)
{
int i;
uint8_t x;
for (i = FPRIME_SIZE - 1; i >= 0; i--)
if (p[i])
break;
x = p[i];
i <<= 3;
while (x) {
x >>= 1;
i++;
}
return i - 1;
}
/* Warning: this function may be variable-time in the argument n */
static void shift_n_bits(uint8_t *x, int n)
{
uint16_t c = 0;
int i;
for (i = 0; i < FPRIME_SIZE; i++) {
c |= ((uint16_t)x[i]) << n;
x[i] = c;
c >>= 8;
}
}
void fprime_load(uint8_t *x, uint32_t c)
{
unsigned int i;
for (i = 0; i < sizeof(c); i++) {
x[i] = c;
c >>= 8;
}
for (; i < FPRIME_SIZE; i++)
x[i] = 0;
}
static inline int min_int(int a, int b)
{
return a < b ? a : b;
}
void fprime_from_bytes(uint8_t *n,
const uint8_t *x, size_t len,
const uint8_t *modulus)
{
const int preload_total = min_int(prime_msb(modulus) - 1, len << 3);
const int preload_bytes = preload_total >> 3;
const int preload_bits = preload_total & 7;
const int rbits = (len << 3) - preload_total;
int i;
memset(n, 0, FPRIME_SIZE);
for (i = 0; i < preload_bytes; i++)
n[i] = x[len - preload_bytes + i];
if (preload_bits) {
shift_n_bits(n, preload_bits);
n[0] |= x[len - preload_bytes - 1] >> (8 - preload_bits);
}
for (i = rbits - 1; i >= 0; i--) {
const uint8_t bit = (x[i >> 3] >> (i & 7)) & 1;
shift_n_bits(n, 1);
n[0] |= bit;
raw_try_sub(n, modulus);
}
}
void fprime_normalize(uint8_t *x, const uint8_t *modulus)
{
uint8_t n[FPRIME_SIZE];
fprime_from_bytes(n, x, FPRIME_SIZE, modulus);
fprime_copy(x, n);
}
uint8_t fprime_eq(const uint8_t *x, const uint8_t *y)
{
uint8_t sum = 0;
int i;
for (i = 0; i < FPRIME_SIZE; i++)
sum |= x[i] ^ y[i];
sum |= (sum >> 4);
sum |= (sum >> 2);
sum |= (sum >> 1);
return (sum ^ 1) & 1;
}
void fprime_select(uint8_t *dst,
const uint8_t *zero, const uint8_t *one,
uint8_t condition)
{
const uint8_t mask = -condition;
int i;
for (i = 0; i < FPRIME_SIZE; i++)
dst[i] = zero[i] ^ (mask & (one[i] ^ zero[i]));
}
void fprime_add(uint8_t *r, const uint8_t *a, const uint8_t *modulus)
{
raw_add(r, a);
raw_try_sub(r, modulus);
}
void fprime_sub(uint8_t *r, const uint8_t *a, const uint8_t *modulus)
{
raw_add(r, modulus);
raw_try_sub(r, a);
raw_try_sub(r, modulus);
}
void fprime_mul(uint8_t *r, const uint8_t *a, const uint8_t *b,
const uint8_t *modulus)
{
int i;
memset(r, 0, FPRIME_SIZE);
for (i = prime_msb(modulus); i >= 0; i--) {
const uint8_t bit = (b[i >> 3] >> (i & 7)) & 1;
uint8_t plusa[FPRIME_SIZE];
shift_n_bits(r, 1);
raw_try_sub(r, modulus);
fprime_copy(plusa, r);
fprime_add(plusa, a, modulus);
fprime_select(r, r, plusa, bit);
}
}
void fprime_inv(uint8_t *r, const uint8_t *a, const uint8_t *modulus)
{
uint8_t pm2[FPRIME_SIZE];
uint16_t c = 2;
int i;
/* Compute (p-2) */
fprime_copy(pm2, modulus);
for (i = 0; i < FPRIME_SIZE; i++) {
c = modulus[i] - c;
pm2[i] = c;
c >>= 8;
}
/* Binary exponentiation */
fprime_load(r, 1);
for (i = prime_msb(modulus); i >= 0; i--) {
uint8_t r2[FPRIME_SIZE];
fprime_mul(r2, r, r, modulus);
if ((pm2[i >> 3] >> (i & 7)) & 1)
fprime_mul(r, r2, a, modulus);
else
fprime_copy(r, r2);
}
}

View file

@ -1,70 +0,0 @@
/* Arithmetic in prime fields
* Daniel Beer <dlbeer@gmail.com>, 10 Jan 2014
*
* This file is in the public domain.
*/
#ifndef FPRIME_H_
#define FPRIME_H_
#include <stdint.h>
#include <string.h>
/* Maximum size of a field element (or a prime). Field elements are
* always manipulated and stored in normalized form, with 0 <= x < p.
* You can use normalize() to convert a denormalized bitstring to normal
* form.
*
* Operations are constant with respect to the value of field elements,
* but not with respect to the modulus.
*
* The modulus is a number p, such that 2p-1 fits in FPRIME_SIZE bytes.
*/
#define FPRIME_SIZE 32
/* Useful constants */
extern const uint8_t fprime_zero[FPRIME_SIZE];
extern const uint8_t fprime_one[FPRIME_SIZE];
/* Load a small constant */
void fprime_load(uint8_t *x, uint32_t c);
/* Load a large constant */
void fprime_from_bytes(uint8_t *x,
const uint8_t *in, size_t len,
const uint8_t *modulus);
/* Copy an element */
static inline void fprime_copy(uint8_t *x, const uint8_t *a)
{
memcpy(x, a, FPRIME_SIZE);
}
/* Normalize a field element */
void fprime_normalize(uint8_t *x, const uint8_t *modulus);
/* Compare two field points in constant time. Return one if equal, zero
* otherwise. This should be performed only on normalized values.
*/
uint8_t fprime_eq(const uint8_t *x, const uint8_t *y);
/* Conditional copy. If condition == 0, then zero is copied to dst. If
* condition == 1, then one is copied to dst. Any other value results in
* undefined behaviour.
*/
void fprime_select(uint8_t *dst,
const uint8_t *zero, const uint8_t *one,
uint8_t condition);
/* Add one value to another. The two pointers must be distinct. */
void fprime_add(uint8_t *r, const uint8_t *a, const uint8_t *modulus);
void fprime_sub(uint8_t *r, const uint8_t *a, const uint8_t *modulus);
/* Multiply two values to get a third. r must be distinct from a and b */
void fprime_mul(uint8_t *r, const uint8_t *a, const uint8_t *b,
const uint8_t *modulus);
/* Compute multiplicative inverse. r must be distinct from a */
void fprime_inv(uint8_t *r, const uint8_t *a, const uint8_t *modulus);
#endif

View file

@ -1,87 +0,0 @@
/* Montgomery <-> Edwards isomorphism
* Daniel Beer <dlbeer@gmail.com>, 18 Jan 2014
*
* This file is in the public domain.
*/
#include "morph25519.h"
#include "f25519.h"
void morph25519_e2m(uint8_t *montgomery, const uint8_t *y)
{
uint8_t yplus[F25519_SIZE];
uint8_t yminus[F25519_SIZE];
f25519_sub(yplus, f25519_one, y);
f25519_inv__distinct(yminus, yplus);
f25519_add(yplus, f25519_one, y);
f25519_mul__distinct(montgomery, yplus, yminus);
f25519_normalize(montgomery);
}
static void mx2ey(uint8_t *ey, const uint8_t *mx)
{
uint8_t n[F25519_SIZE];
uint8_t d[F25519_SIZE];
f25519_add(n, mx, f25519_one);
f25519_inv__distinct(d, n);
f25519_sub(n, mx, f25519_one);
f25519_mul__distinct(ey, n, d);
}
static uint8_t ey2ex(uint8_t *x, const uint8_t *y, int parity)
{
static const uint8_t d[F25519_SIZE] = {
0xa3, 0x78, 0x59, 0x13, 0xca, 0x4d, 0xeb, 0x75,
0xab, 0xd8, 0x41, 0x41, 0x4d, 0x0a, 0x70, 0x00,
0x98, 0xe8, 0x79, 0x77, 0x79, 0x40, 0xc7, 0x8c,
0x73, 0xfe, 0x6f, 0x2b, 0xee, 0x6c, 0x03, 0x52
};
uint8_t a[F25519_SIZE];
uint8_t b[F25519_SIZE];
uint8_t c[F25519_SIZE];
/* Compute c = y^2 */
f25519_mul__distinct(c, y, y);
/* Compute b = (1+dy^2)^-1 */
f25519_mul__distinct(b, c, d);
f25519_add(a, b, f25519_one);
f25519_inv__distinct(b, a);
/* Compute a = y^2-1 */
f25519_sub(a, c, f25519_one);
/* Compute c = a*b = (y^2+1)/(1-dy^2) */
f25519_mul__distinct(c, a, b);
/* Compute a, b = +/-sqrt(c), if c is square */
f25519_sqrt(a, c);
f25519_neg(b, a);
/* Select one of them, based on the parity bit */
f25519_select(x, a, b, (a[0] ^ parity) & 1);
/* Verify that x^2 = c */
f25519_mul__distinct(a, x, x);
f25519_normalize(a);
f25519_normalize(c);
return f25519_eq(a, c);
}
uint8_t morph25519_m2e(uint8_t *ex, uint8_t *ey,
const uint8_t *mx, int parity)
{
uint8_t ok;
mx2ey(ey, mx);
ok = ey2ex(ex, ey, parity);
f25519_normalize(ex);
f25519_normalize(ey);
return ok;
}

View file

@ -1,29 +0,0 @@
/* Montgomery <-> Edwards isomorphism
* Daniel Beer <dlbeer@gmail.com>, 18 Jan 2014
*
* This file is in the public domain.
*/
#ifndef MORPH25519_H_
#define MORPH25519_H_
#include <stdint.h>
/* Convert an Edwards Y to a Montgomery X (Edwards X is not used).
* Resulting coordinate is normalized.
*/
void morph25519_e2m(uint8_t *montgomery_x, const uint8_t *edwards_y);
/* Return a parity bit for the Edwards X coordinate */
static inline int morph25519_eparity(const uint8_t *edwards_x)
{
return edwards_x[0] & 1;
}
/* Convert a Montgomery X and a parity bit to an Edwards X/Y. Returns
* non-zero if successful.
*/
uint8_t morph25519_m2e(uint8_t *ex, uint8_t *ey,
const uint8_t *mx, int parity);
#endif

View file

@ -1,228 +0,0 @@
/* SHA512
* Daniel Beer <dlbeer@gmail.com>, 22 Apr 2014
*
* This file is in the public domain.
*/
#include "sha512.h"
const struct sha512_state sha512_initial_state = { {
0x6a09e667f3bcc908LL, 0xbb67ae8584caa73bLL,
0x3c6ef372fe94f82bLL, 0xa54ff53a5f1d36f1LL,
0x510e527fade682d1LL, 0x9b05688c2b3e6c1fLL,
0x1f83d9abfb41bd6bLL, 0x5be0cd19137e2179LL,
} };
static const uint64_t round_k[80] = {
0x428a2f98d728ae22LL, 0x7137449123ef65cdLL,
0xb5c0fbcfec4d3b2fLL, 0xe9b5dba58189dbbcLL,
0x3956c25bf348b538LL, 0x59f111f1b605d019LL,
0x923f82a4af194f9bLL, 0xab1c5ed5da6d8118LL,
0xd807aa98a3030242LL, 0x12835b0145706fbeLL,
0x243185be4ee4b28cLL, 0x550c7dc3d5ffb4e2LL,
0x72be5d74f27b896fLL, 0x80deb1fe3b1696b1LL,
0x9bdc06a725c71235LL, 0xc19bf174cf692694LL,
0xe49b69c19ef14ad2LL, 0xefbe4786384f25e3LL,
0x0fc19dc68b8cd5b5LL, 0x240ca1cc77ac9c65LL,
0x2de92c6f592b0275LL, 0x4a7484aa6ea6e483LL,
0x5cb0a9dcbd41fbd4LL, 0x76f988da831153b5LL,
0x983e5152ee66dfabLL, 0xa831c66d2db43210LL,
0xb00327c898fb213fLL, 0xbf597fc7beef0ee4LL,
0xc6e00bf33da88fc2LL, 0xd5a79147930aa725LL,
0x06ca6351e003826fLL, 0x142929670a0e6e70LL,
0x27b70a8546d22ffcLL, 0x2e1b21385c26c926LL,
0x4d2c6dfc5ac42aedLL, 0x53380d139d95b3dfLL,
0x650a73548baf63deLL, 0x766a0abb3c77b2a8LL,
0x81c2c92e47edaee6LL, 0x92722c851482353bLL,
0xa2bfe8a14cf10364LL, 0xa81a664bbc423001LL,
0xc24b8b70d0f89791LL, 0xc76c51a30654be30LL,
0xd192e819d6ef5218LL, 0xd69906245565a910LL,
0xf40e35855771202aLL, 0x106aa07032bbd1b8LL,
0x19a4c116b8d2d0c8LL, 0x1e376c085141ab53LL,
0x2748774cdf8eeb99LL, 0x34b0bcb5e19b48a8LL,
0x391c0cb3c5c95a63LL, 0x4ed8aa4ae3418acbLL,
0x5b9cca4f7763e373LL, 0x682e6ff3d6b2b8a3LL,
0x748f82ee5defb2fcLL, 0x78a5636f43172f60LL,
0x84c87814a1f0ab72LL, 0x8cc702081a6439ecLL,
0x90befffa23631e28LL, 0xa4506cebde82bde9LL,
0xbef9a3f7b2c67915LL, 0xc67178f2e372532bLL,
0xca273eceea26619cLL, 0xd186b8c721c0c207LL,
0xeada7dd6cde0eb1eLL, 0xf57d4f7fee6ed178LL,
0x06f067aa72176fbaLL, 0x0a637dc5a2c898a6LL,
0x113f9804bef90daeLL, 0x1b710b35131c471bLL,
0x28db77f523047d84LL, 0x32caab7b40c72493LL,
0x3c9ebe0a15c9bebcLL, 0x431d67c49c100d4cLL,
0x4cc5d4becb3e42b6LL, 0x597f299cfc657e2aLL,
0x5fcb6fab3ad6faecLL, 0x6c44198c4a475817LL,
};
static inline uint64_t load64(const uint8_t *x)
{
uint64_t r;
r = *(x++);
r = (r << 8) | *(x++);
r = (r << 8) | *(x++);
r = (r << 8) | *(x++);
r = (r << 8) | *(x++);
r = (r << 8) | *(x++);
r = (r << 8) | *(x++);
r = (r << 8) | *(x++);
return r;
}
static inline void store64(uint8_t *x, uint64_t v)
{
x += 7;
*(x--) = v;
v >>= 8;
*(x--) = v;
v >>= 8;
*(x--) = v;
v >>= 8;
*(x--) = v;
v >>= 8;
*(x--) = v;
v >>= 8;
*(x--) = v;
v >>= 8;
*(x--) = v;
v >>= 8;
*(x--) = v;
}
static inline uint64_t rot64(uint64_t x, int bits)
{
return (x >> bits) | (x << (64 - bits));
}
void sha512_block(struct sha512_state *s, const uint8_t *blk)
{
uint64_t w[16];
uint64_t a, b, c, d, e, f, g, h;
int i;
for (i = 0; i < 16; i++) {
w[i] = load64(blk);
blk += 8;
}
/* Load state */
a = s->h[0];
b = s->h[1];
c = s->h[2];
d = s->h[3];
e = s->h[4];
f = s->h[5];
g = s->h[6];
h = s->h[7];
for (i = 0; i < 80; i++) {
/* Compute value of w[i + 16]. w[wrap(i)] is currently w[i] */
const uint64_t wi = w[i & 15];
const uint64_t wi15 = w[(i + 1) & 15];
const uint64_t wi2 = w[(i + 14) & 15];
const uint64_t wi7 = w[(i + 9) & 15];
const uint64_t s0 =
rot64(wi15, 1) ^ rot64(wi15, 8) ^ (wi15 >> 7);
const uint64_t s1 =
rot64(wi2, 19) ^ rot64(wi2, 61) ^ (wi2 >> 6);
/* Round calculations */
const uint64_t S0 = rot64(a, 28) ^ rot64(a, 34) ^ rot64(a, 39);
const uint64_t S1 = rot64(e, 14) ^ rot64(e, 18) ^ rot64(e, 41);
const uint64_t ch = (e & f) ^ ((~e) & g);
const uint64_t temp1 = h + S1 + ch + round_k[i] + wi;
const uint64_t maj = (a & b) ^ (a & c) ^ (b & c);
const uint64_t temp2 = S0 + maj;
/* Update round state */
h = g;
g = f;
f = e;
e = d + temp1;
d = c;
c = b;
b = a;
a = temp1 + temp2;
/* w[wrap(i)] becomes w[i + 16] */
w[i & 15] = wi + s0 + wi7 + s1;
}
/* Store state */
s->h[0] += a;
s->h[1] += b;
s->h[2] += c;
s->h[3] += d;
s->h[4] += e;
s->h[5] += f;
s->h[6] += g;
s->h[7] += h;
}
void sha512_final(struct sha512_state *s, const uint8_t *blk,
size_t total_size)
{
uint8_t temp[SHA512_BLOCK_SIZE] = {0};
const size_t last_size = total_size & (SHA512_BLOCK_SIZE - 1);
if (last_size)
memcpy(temp, blk, last_size);
temp[last_size] = 0x80;
if (last_size > 111) {
sha512_block(s, temp);
memset(temp, 0, sizeof(temp));
}
/* Note: we assume total_size fits in 61 bits */
store64(temp + SHA512_BLOCK_SIZE - 8, total_size << 3);
sha512_block(s, temp);
}
void sha512_get(const struct sha512_state *s, uint8_t *hash,
unsigned int offset, unsigned int len)
{
int i;
if (offset > SHA512_BLOCK_SIZE)
return;
if (len > SHA512_BLOCK_SIZE - offset)
len = SHA512_BLOCK_SIZE - offset;
/* Skip whole words */
i = offset >> 3;
offset &= 7;
/* Skip/read out bytes */
if (offset) {
uint8_t tmp[8];
unsigned int c = 8 - offset;
if (c > len)
c = len;
store64(tmp, s->h[i++]);
memcpy(hash, tmp + offset, c);
len -= c;
hash += c;
}
/* Read out whole words */
while (len >= 8) {
store64(hash, s->h[i++]);
hash += 8;
len -= 8;
}
/* Read out bytes */
if (len) {
uint8_t tmp[8];
store64(tmp, s->h[i]);
memcpy(hash, tmp, len);
}
}

View file

@ -1,52 +0,0 @@
/* SHA512
* Daniel Beer <dlbeer@gmail.com>, 22 Apr 2014
*
* This file is in the public domain.
*/
#ifndef SHA512_H_
#define SHA512_H_
#include <stdint.h>
#include <stddef.h>
#include <string.h>
/* SHA512 state. State is updated as data is fed in, and then the final
* hash can be read out in slices.
*
* Data is fed in as a sequence of full blocks terminated by a single
* partial block.
*/
struct sha512_state {
uint64_t h[8];
};
/* Initial state */
extern const struct sha512_state sha512_initial_state;
/* Set up a new context */
static inline void sha512_init(struct sha512_state *s)
{
memcpy(s, &sha512_initial_state, sizeof(*s));
}
/* Feed a full block in */
#define SHA512_BLOCK_SIZE 128
void sha512_block(struct sha512_state *s, const uint8_t *blk);
/* Feed the last partial block in. The total stream size must be
* specified. The size of the block given is assumed to be (total_size %
* SHA512_BLOCK_SIZE). This might be zero, but you still need to call
* this function to terminate the stream.
*/
void sha512_final(struct sha512_state *s, const uint8_t *blk,
size_t total_size);
/* Fetch a slice of the hash result. */
#define SHA512_HASH_SIZE 64
void sha512_get(const struct sha512_state *s, uint8_t *hash,
unsigned int offset, unsigned int len);
#endif

View file

@ -1,95 +0,0 @@
extern "C"
{
int _fltused;
#ifdef _M_IX86 // following functions are needed only for 32-bit architecture
__declspec(naked) void _ftol2()
{
__asm
{
fistp qword ptr [esp-8]
mov edx,[esp-4]
mov eax,[esp-8]
ret
}
}
__declspec(naked) void _ftol2_sse()
{
__asm
{
fistp dword ptr [esp-4]
mov eax,[esp-4]
ret
}
}
#if 0 // these functions are needed for SSE code for 32-bit arch, TODO: implement them
__declspec(naked) void _dtol3()
{
__asm
{
}
}
__declspec(naked) void _dtoui3()
{
__asm
{
}
}
__declspec(naked) void _dtoul3()
{
__asm
{
}
}
__declspec(naked) void _ftol3()
{
__asm
{
}
}
__declspec(naked) void _ftoui3()
{
__asm
{
}
}
__declspec(naked) void _ftoul3()
{
__asm
{
}
}
__declspec(naked) void _ltod3()
{
__asm
{
}
}
__declspec(naked) void _ultod3()
{
__asm
{
}
}
#endif
#endif
}

View file

@ -1,947 +0,0 @@
#ifdef _M_IX86 // use this file only for 32-bit architecture
#define CRT_LOWORD(x) dword ptr [x+0]
#define CRT_HIWORD(x) dword ptr [x+4]
extern "C"
{
__declspec(naked) void _alldiv()
{
#define DVND esp + 16 // stack address of dividend (a)
#define DVSR esp + 24 // stack address of divisor (b)
__asm
{
push edi
push esi
push ebx
; Determine sign of the result (edi = 0 if result is positive, non-zero
; otherwise) and make operands positive.
xor edi,edi ; result sign assumed positive
mov eax,CRT_HIWORD(DVND) ; hi word of a
or eax,eax ; test to see if signed
jge short L1 ; skip rest if a is already positive
inc edi ; complement result sign flag
mov edx,CRT_LOWORD(DVND) ; lo word of a
neg eax ; make a positive
neg edx
sbb eax,0
mov CRT_HIWORD(DVND),eax ; save positive value
mov CRT_LOWORD(DVND),edx
L1:
mov eax,CRT_HIWORD(DVSR) ; hi word of b
or eax,eax ; test to see if signed
jge short L2 ; skip rest if b is already positive
inc edi ; complement the result sign flag
mov edx,CRT_LOWORD(DVSR) ; lo word of a
neg eax ; make b positive
neg edx
sbb eax,0
mov CRT_HIWORD(DVSR),eax ; save positive value
mov CRT_LOWORD(DVSR),edx
L2:
;
; Now do the divide. First look to see if the divisor is less than 4194304K.
; If so, then we can use a simple algorithm with word divides, otherwise
; things get a little more complex.
;
; NOTE - eax currently contains the high order word of DVSR
;
or eax,eax ; check to see if divisor < 4194304K
jnz short L3 ; nope, gotta do this the hard way
mov ecx,CRT_LOWORD(DVSR) ; load divisor
mov eax,CRT_HIWORD(DVND) ; load high word of dividend
xor edx,edx
div ecx ; eax <- high order bits of quotient
mov ebx,eax ; save high bits of quotient
mov eax,CRT_LOWORD(DVND) ; edx:eax <- remainder:lo word of dividend
div ecx ; eax <- low order bits of quotient
mov edx,ebx ; edx:eax <- quotient
jmp short L4 ; set sign, restore stack and return
;
; Here we do it the hard way. Remember, eax contains the high word of DVSR
;
L3:
mov ebx,eax ; ebx:ecx <- divisor
mov ecx,CRT_LOWORD(DVSR)
mov edx,CRT_HIWORD(DVND) ; edx:eax <- dividend
mov eax,CRT_LOWORD(DVND)
L5:
shr ebx,1 ; shift divisor right one bit
rcr ecx,1
shr edx,1 ; shift dividend right one bit
rcr eax,1
or ebx,ebx
jnz short L5 ; loop until divisor < 4194304K
div ecx ; now divide, ignore remainder
mov esi,eax ; save quotient
;
; We may be off by one, so to check, we will multiply the quotient
; by the divisor and check the result against the orignal dividend
; Note that we must also check for overflow, which can occur if the
; dividend is close to 2**64 and the quotient is off by 1.
;
mul CRT_HIWORD(DVSR) ; QUOT * CRT_HIWORD(DVSR)
mov ecx,eax
mov eax,CRT_LOWORD(DVSR)
mul esi ; QUOT * CRT_LOWORD(DVSR)
add edx,ecx ; EDX:EAX = QUOT * DVSR
jc short L6 ; carry means Quotient is off by 1
;
; do long compare here between original dividend and the result of the
; multiply in edx:eax. If original is larger or equal, we are ok, otherwise
; subtract one (1) from the quotient.
;
cmp edx,CRT_HIWORD(DVND) ; compare hi words of result and original
ja short L6 ; if result > original, do subtract
jb short L7 ; if result < original, we are ok
cmp eax,CRT_LOWORD(DVND) ; hi words are equal, compare lo words
jbe short L7 ; if less or equal we are ok, else subtract
L6:
dec esi ; subtract 1 from quotient
L7:
xor edx,edx ; edx:eax <- quotient
mov eax,esi
;
; Just the cleanup left to do. edx:eax contains the quotient. Set the sign
; according to the save value, cleanup the stack, and return.
;
L4:
dec edi ; check to see if result is negative
jnz short L8 ; if EDI == 0, result should be negative
neg edx ; otherwise, negate the result
neg eax
sbb edx,0
;
; Restore the saved registers and return.
;
L8:
pop ebx
pop esi
pop edi
ret 16
}
#undef DVND
#undef DVSR
}
__declspec(naked) void _alldvrm()
{
#define DVND esp + 16 // stack address of dividend (a)
#define DVSR esp + 24 // stack address of divisor (b)
__asm
{
push edi
push esi
push ebp
; Determine sign of the quotient (edi = 0 if result is positive, non-zero
; otherwise) and make operands positive.
; Sign of the remainder is kept in ebp.
xor edi,edi ; result sign assumed positive
xor ebp,ebp ; result sign assumed positive
mov eax,CRT_HIWORD(DVND) ; hi word of a
or eax,eax ; test to see if signed
jge short L1 ; skip rest if a is already positive
inc edi ; complement result sign flag
inc ebp ; complement result sign flag
mov edx,CRT_LOWORD(DVND) ; lo word of a
neg eax ; make a positive
neg edx
sbb eax,0
mov CRT_HIWORD(DVND),eax ; save positive value
mov CRT_LOWORD(DVND),edx
L1:
mov eax,CRT_HIWORD(DVSR) ; hi word of b
or eax,eax ; test to see if signed
jge short L2 ; skip rest if b is already positive
inc edi ; complement the result sign flag
mov edx,CRT_LOWORD(DVSR) ; lo word of a
neg eax ; make b positive
neg edx
sbb eax,0
mov CRT_HIWORD(DVSR),eax ; save positive value
mov CRT_LOWORD(DVSR),edx
L2:
;
; Now do the divide. First look to see if the divisor is less than 4194304K.
; If so, then we can use a simple algorithm with word divides, otherwise
; things get a little more complex.
;
; NOTE - eax currently contains the high order word of DVSR
;
or eax,eax ; check to see if divisor < 4194304K
jnz short L3 ; nope, gotta do this the hard way
mov ecx,CRT_LOWORD(DVSR) ; load divisor
mov eax,CRT_HIWORD(DVND) ; load high word of dividend
xor edx,edx
div ecx ; eax <- high order bits of quotient
mov ebx,eax ; save high bits of quotient
mov eax,CRT_LOWORD(DVND) ; edx:eax <- remainder:lo word of dividend
div ecx ; eax <- low order bits of quotient
mov esi,eax ; ebx:esi <- quotient
;
; Now we need to do a multiply so that we can compute the remainder.
;
mov eax,ebx ; set up high word of quotient
mul CRT_LOWORD(DVSR) ; CRT_HIWORD(QUOT) * DVSR
mov ecx,eax ; save the result in ecx
mov eax,esi ; set up low word of quotient
mul CRT_LOWORD(DVSR) ; CRT_LOWORD(QUOT) * DVSR
add edx,ecx ; EDX:EAX = QUOT * DVSR
jmp short L4 ; complete remainder calculation
;
; Here we do it the hard way. Remember, eax contains the high word of DVSR
;
L3:
mov ebx,eax ; ebx:ecx <- divisor
mov ecx,CRT_LOWORD(DVSR)
mov edx,CRT_HIWORD(DVND) ; edx:eax <- dividend
mov eax,CRT_LOWORD(DVND)
L5:
shr ebx,1 ; shift divisor right one bit
rcr ecx,1
shr edx,1 ; shift dividend right one bit
rcr eax,1
or ebx,ebx
jnz short L5 ; loop until divisor < 4194304K
div ecx ; now divide, ignore remainder
mov esi,eax ; save quotient
;
; We may be off by one, so to check, we will multiply the quotient
; by the divisor and check the result against the orignal dividend
; Note that we must also check for overflow, which can occur if the
; dividend is close to 2**64 and the quotient is off by 1.
;
mul CRT_HIWORD(DVSR) ; QUOT * CRT_HIWORD(DVSR)
mov ecx,eax
mov eax,CRT_LOWORD(DVSR)
mul esi ; QUOT * CRT_LOWORD(DVSR)
add edx,ecx ; EDX:EAX = QUOT * DVSR
jc short L6 ; carry means Quotient is off by 1
;
; do long compare here between original dividend and the result of the
; multiply in edx:eax. If original is larger or equal, we are ok, otherwise
; subtract one (1) from the quotient.
;
cmp edx,CRT_HIWORD(DVND) ; compare hi words of result and original
ja short L6 ; if result > original, do subtract
jb short L7 ; if result < original, we are ok
cmp eax,CRT_LOWORD(DVND) ; hi words are equal, compare lo words
jbe short L7 ; if less or equal we are ok, else subtract
L6:
dec esi ; subtract 1 from quotient
sub eax,CRT_LOWORD(DVSR) ; subtract divisor from result
sbb edx,CRT_HIWORD(DVSR)
L7:
xor ebx,ebx ; ebx:esi <- quotient
L4:
;
; Calculate remainder by subtracting the result from the original dividend.
; Since the result is already in a register, we will do the subtract in the
; opposite direction and negate the result if necessary.
;
sub eax,CRT_LOWORD(DVND) ; subtract dividend from result
sbb edx,CRT_HIWORD(DVND)
;
; Now check the result sign flag to see if the result is supposed to be positive
; or negative. It is currently negated (because we subtracted in the 'wrong'
; direction), so if the sign flag is set we are done, otherwise we must negate
; the result to make it positive again.
;
dec ebp ; check result sign flag
jns short L9 ; result is ok, set up the quotient
neg edx ; otherwise, negate the result
neg eax
sbb edx,0
;
; Now we need to get the quotient into edx:eax and the remainder into ebx:ecx.
;
L9:
mov ecx,edx
mov edx,ebx
mov ebx,ecx
mov ecx,eax
mov eax,esi
;
; Just the cleanup left to do. edx:eax contains the quotient. Set the sign
; according to the save value, cleanup the stack, and return.
;
dec edi ; check to see if result is negative
jnz short L8 ; if EDI == 0, result should be negative
neg edx ; otherwise, negate the result
neg eax
sbb edx,0
;
; Restore the saved registers and return.
;
L8:
pop ebp
pop esi
pop edi
ret 16
}
#undef DVND
#undef DVSR
}
__declspec(naked) void _allmul()
{
#define A esp + 8 // stack address of a
#define B esp + 16 // stack address of b
__asm
{
push ebx
mov eax,CRT_HIWORD(A)
mov ecx,CRT_LOWORD(B)
mul ecx ;eax has AHI, ecx has BLO, so AHI * BLO
mov ebx,eax ;save result
mov eax,CRT_LOWORD(A)
mul CRT_HIWORD(B) ;ALO * BHI
add ebx,eax ;ebx = ((ALO * BHI) + (AHI * BLO))
mov eax,CRT_LOWORD(A) ;ecx = BLO
mul ecx ;so edx:eax = ALO*BLO
add edx,ebx ;now edx has all the LO*HI stuff
pop ebx
ret 16 ; callee restores the stack
}
#undef A
#undef B
}
__declspec(naked) void _allrem()
{
#define DVND esp + 12 // stack address of dividend (a)
#define DVSR esp + 20 // stack address of divisor (b)
__asm
{
push ebx
push edi
; Determine sign of the result (edi = 0 if result is positive, non-zero
; otherwise) and make operands positive.
xor edi,edi ; result sign assumed positive
mov eax,CRT_HIWORD(DVND) ; hi word of a
or eax,eax ; test to see if signed
jge short L1 ; skip rest if a is already positive
inc edi ; complement result sign flag bit
mov edx,CRT_LOWORD(DVND) ; lo word of a
neg eax ; make a positive
neg edx
sbb eax,0
mov CRT_HIWORD(DVND),eax ; save positive value
mov CRT_LOWORD(DVND),edx
L1:
mov eax,CRT_HIWORD(DVSR) ; hi word of b
or eax,eax ; test to see if signed
jge short L2 ; skip rest if b is already positive
mov edx,CRT_LOWORD(DVSR) ; lo word of b
neg eax ; make b positive
neg edx
sbb eax,0
mov CRT_HIWORD(DVSR),eax ; save positive value
mov CRT_LOWORD(DVSR),edx
L2:
;
; Now do the divide. First look to see if the divisor is less than 4194304K.
; If so, then we can use a simple algorithm with word divides, otherwise
; things get a little more complex.
;
; NOTE - eax currently contains the high order word of DVSR
;
or eax,eax ; check to see if divisor < 4194304K
jnz short L3 ; nope, gotta do this the hard way
mov ecx,CRT_LOWORD(DVSR) ; load divisor
mov eax,CRT_HIWORD(DVND) ; load high word of dividend
xor edx,edx
div ecx ; edx <- remainder
mov eax,CRT_LOWORD(DVND) ; edx:eax <- remainder:lo word of dividend
div ecx ; edx <- final remainder
mov eax,edx ; edx:eax <- remainder
xor edx,edx
dec edi ; check result sign flag
jns short L4 ; negate result, restore stack and return
jmp short L8 ; result sign ok, restore stack and return
;
; Here we do it the hard way. Remember, eax contains the high word of DVSR
;
L3:
mov ebx,eax ; ebx:ecx <- divisor
mov ecx,CRT_LOWORD(DVSR)
mov edx,CRT_HIWORD(DVND) ; edx:eax <- dividend
mov eax,CRT_LOWORD(DVND)
L5:
shr ebx,1 ; shift divisor right one bit
rcr ecx,1
shr edx,1 ; shift dividend right one bit
rcr eax,1
or ebx,ebx
jnz short L5 ; loop until divisor < 4194304K
div ecx ; now divide, ignore remainder
;
; We may be off by one, so to check, we will multiply the quotient
; by the divisor and check the result against the orignal dividend
; Note that we must also check for overflow, which can occur if the
; dividend is close to 2**64 and the quotient is off by 1.
;
mov ecx,eax ; save a copy of quotient in ECX
mul CRT_HIWORD(DVSR)
xchg ecx,eax ; save product, get quotient in EAX
mul CRT_LOWORD(DVSR)
add edx,ecx ; EDX:EAX = QUOT * DVSR
jc short L6 ; carry means Quotient is off by 1
;
; do long compare here between original dividend and the result of the
; multiply in edx:eax. If original is larger or equal, we are ok, otherwise
; subtract the original divisor from the result.
;
cmp edx,CRT_HIWORD(DVND) ; compare hi words of result and original
ja short L6 ; if result > original, do subtract
jb short L7 ; if result < original, we are ok
cmp eax,CRT_LOWORD(DVND) ; hi words are equal, compare lo words
jbe short L7 ; if less or equal we are ok, else subtract
L6:
sub eax,CRT_LOWORD(DVSR) ; subtract divisor from result
sbb edx,CRT_HIWORD(DVSR)
L7:
;
; Calculate remainder by subtracting the result from the original dividend.
; Since the result is already in a register, we will do the subtract in the
; opposite direction and negate the result if necessary.
;
sub eax,CRT_LOWORD(DVND) ; subtract dividend from result
sbb edx,CRT_HIWORD(DVND)
;
; Now check the result sign flag to see if the result is supposed to be positive
; or negative. It is currently negated (because we subtracted in the 'wrong'
; direction), so if the sign flag is set we are done, otherwise we must negate
; the result to make it positive again.
;
dec edi ; check result sign flag
jns short L8 ; result is ok, restore stack and return
L4:
neg edx ; otherwise, negate the result
neg eax
sbb edx,0
;
; Just the cleanup left to do. edx:eax contains the quotient.
; Restore the saved registers and return.
;
L8:
pop edi
pop ebx
ret 16
}
#undef DVND
#undef DVSR
}
__declspec(naked) void _allshl()
{
__asm
{
;
; Handle shifts of 64 or more bits (all get 0)
;
cmp cl, 64
jae short RETZERO
;
; Handle shifts of between 0 and 31 bits
;
cmp cl, 32
jae short MORE32
shld edx,eax,cl
shl eax,cl
ret
;
; Handle shifts of between 32 and 63 bits
;
MORE32:
mov edx,eax
xor eax,eax
and cl,31
shl edx,cl
ret
;
; return 0 in edx:eax
;
RETZERO:
xor eax,eax
xor edx,edx
ret
}
}
__declspec(naked) void _allshr()
{
__asm
{
;
; Handle shifts of 64 bits or more (if shifting 64 bits or more, the result
; depends only on the high order bit of edx).
;
cmp cl,64
jae short RETSIGN
;
; Handle shifts of between 0 and 31 bits
;
cmp cl, 32
jae short MORE32
shrd eax,edx,cl
sar edx,cl
ret
;
; Handle shifts of between 32 and 63 bits
;
MORE32:
mov eax,edx
sar edx,31
and cl,31
sar eax,cl
ret
;
; Return double precision 0 or -1, depending on the sign of edx
;
RETSIGN:
sar edx,31
mov eax,edx
ret
}
}
__declspec(naked) void _aulldiv()
{
#define DVND esp + 12 // stack address of dividend (a)
#define DVSR esp + 20 // stack address of divisor (b)
__asm
{
push ebx
push esi
;
; Now do the divide. First look to see if the divisor is less than 4194304K.
; If so, then we can use a simple algorithm with word divides, otherwise
; things get a little more complex.
;
mov eax,CRT_HIWORD(DVSR) ; check to see if divisor < 4194304K
or eax,eax
jnz short L1 ; nope, gotta do this the hard way
mov ecx,CRT_LOWORD(DVSR) ; load divisor
mov eax,CRT_HIWORD(DVND) ; load high word of dividend
xor edx,edx
div ecx ; get high order bits of quotient
mov ebx,eax ; save high bits of quotient
mov eax,CRT_LOWORD(DVND) ; edx:eax <- remainder:lo word of dividend
div ecx ; get low order bits of quotient
mov edx,ebx ; edx:eax <- quotient hi:quotient lo
jmp short L2 ; restore stack and return
;
; Here we do it the hard way. Remember, eax contains DVSRHI
;
L1:
mov ecx,eax ; ecx:ebx <- divisor
mov ebx,CRT_LOWORD(DVSR)
mov edx,CRT_HIWORD(DVND) ; edx:eax <- dividend
mov eax,CRT_LOWORD(DVND)
L3:
shr ecx,1 ; shift divisor right one bit; hi bit <- 0
rcr ebx,1
shr edx,1 ; shift dividend right one bit; hi bit <- 0
rcr eax,1
or ecx,ecx
jnz short L3 ; loop until divisor < 4194304K
div ebx ; now divide, ignore remainder
mov esi,eax ; save quotient
;
; We may be off by one, so to check, we will multiply the quotient
; by the divisor and check the result against the orignal dividend
; Note that we must also check for overflow, which can occur if the
; dividend is close to 2**64 and the quotient is off by 1.
;
mul CRT_HIWORD(DVSR) ; QUOT * CRT_HIWORD(DVSR)
mov ecx,eax
mov eax,CRT_LOWORD(DVSR)
mul esi ; QUOT * CRT_LOWORD(DVSR)
add edx,ecx ; EDX:EAX = QUOT * DVSR
jc short L4 ; carry means Quotient is off by 1
;
; do long compare here between original dividend and the result of the
; multiply in edx:eax. If original is larger or equal, we are ok, otherwise
; subtract one (1) from the quotient.
;
cmp edx,CRT_HIWORD(DVND) ; compare hi words of result and original
ja short L4 ; if result > original, do subtract
jb short L5 ; if result < original, we are ok
cmp eax,CRT_LOWORD(DVND) ; hi words are equal, compare lo words
jbe short L5 ; if less or equal we are ok, else subtract
L4:
dec esi ; subtract 1 from quotient
L5:
xor edx,edx ; edx:eax <- quotient
mov eax,esi
;
; Just the cleanup left to do. edx:eax contains the quotient.
; Restore the saved registers and return.
;
L2:
pop esi
pop ebx
ret 16
}
#undef DVND
#undef DVSR
}
__declspec(naked) void _aulldvrm()
{
#define DVND esp + 8 // stack address of dividend (a)
#define DVSR esp + 16 // stack address of divisor (b)
__asm
{
push esi
;
; Now do the divide. First look to see if the divisor is less than 4194304K.
; If so, then we can use a simple algorithm with word divides, otherwise
; things get a little more complex.
;
mov eax,CRT_HIWORD(DVSR) ; check to see if divisor < 4194304K
or eax,eax
jnz short L1 ; nope, gotta do this the hard way
mov ecx,CRT_LOWORD(DVSR) ; load divisor
mov eax,CRT_HIWORD(DVND) ; load high word of dividend
xor edx,edx
div ecx ; get high order bits of quotient
mov ebx,eax ; save high bits of quotient
mov eax,CRT_LOWORD(DVND) ; edx:eax <- remainder:lo word of dividend
div ecx ; get low order bits of quotient
mov esi,eax ; ebx:esi <- quotient
;
; Now we need to do a multiply so that we can compute the remainder.
;
mov eax,ebx ; set up high word of quotient
mul CRT_LOWORD(DVSR) ; CRT_HIWORD(QUOT) * DVSR
mov ecx,eax ; save the result in ecx
mov eax,esi ; set up low word of quotient
mul CRT_LOWORD(DVSR) ; CRT_LOWORD(QUOT) * DVSR
add edx,ecx ; EDX:EAX = QUOT * DVSR
jmp short L2 ; complete remainder calculation
;
; Here we do it the hard way. Remember, eax contains DVSRHI
;
L1:
mov ecx,eax ; ecx:ebx <- divisor
mov ebx,CRT_LOWORD(DVSR)
mov edx,CRT_HIWORD(DVND) ; edx:eax <- dividend
mov eax,CRT_LOWORD(DVND)
L3:
shr ecx,1 ; shift divisor right one bit; hi bit <- 0
rcr ebx,1
shr edx,1 ; shift dividend right one bit; hi bit <- 0
rcr eax,1
or ecx,ecx
jnz short L3 ; loop until divisor < 4194304K
div ebx ; now divide, ignore remainder
mov esi,eax ; save quotient
;
; We may be off by one, so to check, we will multiply the quotient
; by the divisor and check the result against the orignal dividend
; Note that we must also check for overflow, which can occur if the
; dividend is close to 2**64 and the quotient is off by 1.
;
mul CRT_HIWORD(DVSR) ; QUOT * CRT_HIWORD(DVSR)
mov ecx,eax
mov eax,CRT_LOWORD(DVSR)
mul esi ; QUOT * CRT_LOWORD(DVSR)
add edx,ecx ; EDX:EAX = QUOT * DVSR
jc short L4 ; carry means Quotient is off by 1
;
; do long compare here between original dividend and the result of the
; multiply in edx:eax. If original is larger or equal, we are ok, otherwise
; subtract one (1) from the quotient.
;
cmp edx,CRT_HIWORD(DVND) ; compare hi words of result and original
ja short L4 ; if result > original, do subtract
jb short L5 ; if result < original, we are ok
cmp eax,CRT_LOWORD(DVND) ; hi words are equal, compare lo words
jbe short L5 ; if less or equal we are ok, else subtract
L4:
dec esi ; subtract 1 from quotient
sub eax,CRT_LOWORD(DVSR) ; subtract divisor from result
sbb edx,CRT_HIWORD(DVSR)
L5:
xor ebx,ebx ; ebx:esi <- quotient
L2:
;
; Calculate remainder by subtracting the result from the original dividend.
; Since the result is already in a register, we will do the subtract in the
; opposite direction and negate the result.
;
sub eax,CRT_LOWORD(DVND) ; subtract dividend from result
sbb edx,CRT_HIWORD(DVND)
neg edx ; otherwise, negate the result
neg eax
sbb edx,0
;
; Now we need to get the quotient into edx:eax and the remainder into ebx:ecx.
;
mov ecx,edx
mov edx,ebx
mov ebx,ecx
mov ecx,eax
mov eax,esi
;
; Just the cleanup left to do. edx:eax contains the quotient.
; Restore the saved registers and return.
;
pop esi
ret 16
}
#undef DVND
#undef DVSR
}
__declspec(naked) void _aullrem()
{
#define DVND esp + 8 // stack address of dividend (a)
#define DVSR esp + 16 // stack address of divisor (b)
__asm
{
push ebx
; Now do the divide. First look to see if the divisor is less than 4194304K.
; If so, then we can use a simple algorithm with word divides, otherwise
; things get a little more complex.
;
mov eax,CRT_HIWORD(DVSR) ; check to see if divisor < 4194304K
or eax,eax
jnz short L1 ; nope, gotta do this the hard way
mov ecx,CRT_LOWORD(DVSR) ; load divisor
mov eax,CRT_HIWORD(DVND) ; load high word of dividend
xor edx,edx
div ecx ; edx <- remainder, eax <- quotient
mov eax,CRT_LOWORD(DVND) ; edx:eax <- remainder:lo word of dividend
div ecx ; edx <- final remainder
mov eax,edx ; edx:eax <- remainder
xor edx,edx
jmp short L2 ; restore stack and return
;
; Here we do it the hard way. Remember, eax contains DVSRHI
;
L1:
mov ecx,eax ; ecx:ebx <- divisor
mov ebx,CRT_LOWORD(DVSR)
mov edx,CRT_HIWORD(DVND) ; edx:eax <- dividend
mov eax,CRT_LOWORD(DVND)
L3:
shr ecx,1 ; shift divisor right one bit; hi bit <- 0
rcr ebx,1
shr edx,1 ; shift dividend right one bit; hi bit <- 0
rcr eax,1
or ecx,ecx
jnz short L3 ; loop until divisor < 4194304K
div ebx ; now divide, ignore remainder
;
; We may be off by one, so to check, we will multiply the quotient
; by the divisor and check the result against the orignal dividend
; Note that we must also check for overflow, which can occur if the
; dividend is close to 2**64 and the quotient is off by 1.
;
mov ecx,eax ; save a copy of quotient in ECX
mul CRT_HIWORD(DVSR)
xchg ecx,eax ; put partial product in ECX, get quotient in EAX
mul CRT_LOWORD(DVSR)
add edx,ecx ; EDX:EAX = QUOT * DVSR
jc short L4 ; carry means Quotient is off by 1
;
; do long compare here between original dividend and the result of the
; multiply in edx:eax. If original is larger or equal, we're ok, otherwise
; subtract the original divisor from the result.
;
cmp edx,CRT_HIWORD(DVND) ; compare hi words of result and original
ja short L4 ; if result > original, do subtract
jb short L5 ; if result < original, we're ok
cmp eax,CRT_LOWORD(DVND) ; hi words are equal, compare lo words
jbe short L5 ; if less or equal we're ok, else subtract
L4:
sub eax,CRT_LOWORD(DVSR) ; subtract divisor from result
sbb edx,CRT_HIWORD(DVSR)
L5:
;
; Calculate remainder by subtracting the result from the original dividend.
; Since the result is already in a register, we will perform the subtract in
; the opposite direction and negate the result to make it positive.
;
sub eax,CRT_LOWORD(DVND) ; subtract original dividend from result
sbb edx,CRT_HIWORD(DVND)
neg edx ; and negate it
neg eax
sbb edx,0
;
; Just the cleanup left to do. dx:ax contains the remainder.
; Restore the saved registers and return.
;
L2:
pop ebx
ret 16
}
#undef DVND
#undef DVSR
}
__declspec(naked) void _aullshr()
{
__asm
{
cmp cl,64
jae short RETZERO
;
; Handle shifts of between 0 and 31 bits
;
cmp cl, 32
jae short MORE32
shrd eax,edx,cl
shr edx,cl
ret
;
; Handle shifts of between 32 and 63 bits
;
MORE32:
mov eax,edx
xor edx,edx
and cl,31
shr eax,cl
ret
;
; return 0 in edx:eax
;
RETZERO:
xor eax,eax
xor edx,edx
ret
}
}
}
#undef CRT_LOWORD
#undef CRT_HIWORD
#endif

View file

@ -1,26 +0,0 @@
#include <string.h>
extern "C"
{
#pragma function(memset)
void *memset(void *dest, int c, size_t count)
{
char *bytes = (char *)dest;
while (count--)
{
*bytes++ = (char)c;
}
return dest;
}
#pragma function(memcpy)
void *memcpy(void *dest, const void *src, size_t count)
{
char *dest8 = (char *)dest;
const char *src8 = (const char *)src;
while (count--)
{
*dest8++ = *src8++;
}
return dest;
}
}

View file

@ -1,99 +0,0 @@
extern "C"
{
#if _M_IX86
EXCEPTION_DISPOSITION
_except_handler3(
struct _EXCEPTION_RECORD* ExceptionRecord,
void* EstablisherFrame,
struct _CONTEXT* ContextRecord,
void* DispatcherContext)
{
typedef EXCEPTION_DISPOSITION Function(struct _EXCEPTION_RECORD*, void*, struct _CONTEXT*, void*);
static Function* FunctionPtr;
if (!FunctionPtr)
{
HMODULE Library = LoadLibraryA("msvcrt.dll");
FunctionPtr = (Function*)GetProcAddress(Library, "_except_handler3");
}
return FunctionPtr(ExceptionRecord, EstablisherFrame, ContextRecord, DispatcherContext);
}
UINT_PTR __security_cookie = 0xBB40E64E;
extern PVOID __safe_se_handler_table[];
extern BYTE __safe_se_handler_count;
typedef struct {
DWORD Size;
DWORD TimeDateStamp;
WORD MajorVersion;
WORD MinorVersion;
DWORD GlobalFlagsClear;
DWORD GlobalFlagsSet;
DWORD CriticalSectionDefaultTimeout;
DWORD DeCommitFreeBlockThreshold;
DWORD DeCommitTotalFreeThreshold;
DWORD LockPrefixTable;
DWORD MaximumAllocationSize;
DWORD VirtualMemoryThreshold;
DWORD ProcessHeapFlags;
DWORD ProcessAffinityMask;
WORD CSDVersion;
WORD Reserved1;
DWORD EditList;
PUINT_PTR SecurityCookie;
PVOID *SEHandlerTable;
DWORD SEHandlerCount;
} IMAGE_LOAD_CONFIG_DIRECTORY32_2;
const
IMAGE_LOAD_CONFIG_DIRECTORY32_2 _load_config_used = {
sizeof(IMAGE_LOAD_CONFIG_DIRECTORY32_2),
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
&__security_cookie,
__safe_se_handler_table,
(DWORD)(DWORD_PTR) &__safe_se_handler_count
};
#elif _M_AMD64
EXCEPTION_DISPOSITION
__C_specific_handler(
struct _EXCEPTION_RECORD* ExceptionRecord,
void* EstablisherFrame,
struct _CONTEXT* ContextRecord,
struct _DISPATCHER_CONTEXT* DispatcherContext)
{
typedef EXCEPTION_DISPOSITION Function(struct _EXCEPTION_RECORD*, void*, struct _CONTEXT*, _DISPATCHER_CONTEXT*);
static Function* FunctionPtr;
if (!FunctionPtr)
{
HMODULE Library = LoadLibraryA("msvcrt.dll");
FunctionPtr = (Function*)GetProcAddress(Library, "__C_specific_handler");
}
return FunctionPtr(ExceptionRecord, EstablisherFrame, ContextRecord, DispatcherContext);
}
#endif
}

View file

@ -1,2 +1 @@
/TunSafe-TAP-auto.exe.sig
/TunSafe-TAP-auto.exe
/TunSafe-TAP Installer.exe

View file

@ -49,7 +49,7 @@ Name "${PRODUCT_NAME}"
!insertmacro MUI_LANGUAGE "English"
LangString DESC_SecTAP ${LANG_ENGLISH} "Install the TunSafe client."
LangString DESC_SecTapAdapter ${LANG_ENGLISH} "Download and Install the TunSafe-TAP Virtual Ethernet Adapter (GPL)."
LangString DESC_SecTapAdapter ${LANG_ENGLISH} "Install the TunSafe-TAP Virtual Ethernet Adapter (GPL)."
Section "TunSafe Client" SecTunSafe
SetOverwrite on
@ -76,34 +76,9 @@ SectionEnd
Section "TunSafe-TAP Ethernet Adapter (GPL)" SecTapAdapter
SetOverwrite on
Delete "$INSTDIR\tunsafe-tap-installer.exe"
NSISdl::download http://tunsafe.com/downloads/TunSafe-TAP-auto.exe "$INSTDIR\TunSafe-TAP Installer.exe"
Pop $R0 ;Get the return value
${Unless} $R0 == "success"
MessageBox MB_ICONEXCLAMATION "An error occurred while downloading the TunSafe-TAP Virtual Ethernet Adapter. The installer will now abort."
SetErrorLevel 1
Quit
${EndUnless}
NSISdl::download http://tunsafe.com/downloads/TunSafe-TAP-auto.exe.sig "$INSTDIR\TunSafe-TAP Installer.exe.sig"
${Unless} $R0 == "success"
Delete "$INSTDIR\TunSafe-TAP Installer.exe.sig"
MessageBox MB_ICONEXCLAMATION "An error occurred while downloading the TunSafe-TAP Virtual Ethernet Adapter. The installer will now abort."
SetErrorLevel 1
Quit
${EndUnless}
SignPlugin::myFunction "$INSTDIR\TunSafe-TAP Installer.exe"
Pop $R1 ;Get the return value
Delete "$INSTDIR\TunSafe-TAP Installer.exe.sig"
${Unless} $R1 = 0
MessageBox MB_ICONEXCLAMATION "The TunSafe-TAP installer that was downloaded is broken (error $R1). The installer will now abort."
SetErrorLevel 1
Quit
${EndUnless}
SetOutPath "$INSTDIR"
File "tap\TunSafe-TAP Installer.exe"
HideWindow
# Launch TunSafe-TAP installer