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 10.IPv6 endpoint was printed incorrectly on the Advanced tab
11.Show an error message and drop packets if the TUN queue grows 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. 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 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 Installer.exe
/TunSafe-TAP-auto.exe

View file

@ -49,7 +49,7 @@ Name "${PRODUCT_NAME}"
!insertmacro MUI_LANGUAGE "English" !insertmacro MUI_LANGUAGE "English"
LangString DESC_SecTAP ${LANG_ENGLISH} "Install the TunSafe client." 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 Section "TunSafe Client" SecTunSafe
SetOverwrite on SetOverwrite on
@ -76,34 +76,9 @@ SectionEnd
Section "TunSafe-TAP Ethernet Adapter (GPL)" SecTapAdapter Section "TunSafe-TAP Ethernet Adapter (GPL)" SecTapAdapter
SetOverwrite on SetOverwrite on
Delete "$INSTDIR\tunsafe-tap-installer.exe" SetOutPath "$INSTDIR"
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}
File "tap\TunSafe-TAP Installer.exe"
HideWindow HideWindow
# Launch TunSafe-TAP installer # Launch TunSafe-TAP installer