Permalink
Browse files

added pure pascal version of SynECC.pas

- thanks Jerome for sharing the code of your XMLRad ECC.pas
  • Loading branch information...
Arnaud Bouchez
Arnaud Bouchez committed Dec 4, 2017
1 parent 385a35e commit bc405cffb7bfb79646b46a6afc13968a0d804f32
Showing with 1,242 additions and 148 deletions.
  1. +2 −2 SQLite3/Documentation/Synopse SQLite3 Framework.pro
  2. +0 −2 SQLite3/Samples/33 - ECC/ECCProcess.pas
  3. +70 −0 SynCommons.pas
  4. +1,140 −53 SynEcc.pas
  5. +0 −61 SynMongoDB.pas
  6. +27 −29 SynSelfTests.pas
  7. +2 −0 Synopse.inc
  8. +1 −1 SynopseCommit.inc
@@ -14184,7 +14184,7 @@ There will no doubt be criticism of our decision to re-implement a whole public-
;- Having our own embedded code is safer than using the old/unsafe already installed libraries, especially on an existing server (what is the OpenSSL version in your good old Debian VM?);
;- It was fun, we learned a lot, and we hope you will enjoy using it, and contribute to it!
: Introducing SynEcc
The {\i mORMot}'s {\f1\fs20 SynEcc.pas} unit implements full ECC computation, using {\f1\fs20 secp256r1} curve, i.e. {\f1\fs20 NIST P-256}, or OpenSSL's {\f1\fs20 prime256v1}. The low-level computation is done in optimized C code - from the @https://github.com/esxgx/easy-ecc {\i Open Source} project - and is statically linked in your Windows or Linux executable: i.e. no external {\f1\fs20 .dll}/{\f1\fs20 .so} library is needed. Then we defined a feature-rich set of object pascal classes on top of this solid ECC ground, to include certificates, safe storage of private keys, JSON publication of public keys, as an integrated toolset.
The {\i mORMot}'s {\f1\fs20 SynEcc.pas} unit implements full ECC computation, using {\f1\fs20 secp256r1} curve, i.e. {\f1\fs20 NIST P-256}, or OpenSSL's {\f1\fs20 prime256v1}. The low-level computation is done in optimized C code - from the @https://github.com/esxgx/easy-ecc {\i Open Source} project - and is statically linked in your Windows or Linux executable: i.e. no external {\f1\fs20 .dll}/{\f1\fs20 .so} library is needed. On targets (e.g. BSD/MacOSX or ARM) where we didn't provide the static {\f1\fs20 .o} files, there is an optimized pascal version available. Then we defined a feature-rich set of object pascal classes on top of this solid ECC ground, to include certificates, safe storage of private keys, JSON publication of public keys, as an integrated toolset.
All needed low-level asymmetric cryptography is available:
- ECC key generation, using {\f1\fs20 SynCrypto.pas}'s secure {\f1\fs20 TAESPRNG} as random seed;
- ECDSA signature and verification of 256-bit hashes;
@@ -16145,7 +16145,7 @@ Therefore, {\f1\fs20 sqlite3.obj} and {\f1\fs20 sqlite3fts.obj} files are availa
Please download the latest compiled version of these {\f1\fs20 .obj} files from this link. You can also use the supplied {\f1\fs20 c.bat} file to compile from the original {\f1\fs20 sqlite3.c} file available in the repository, if you have the {\f1\fs20 bcc32} C command-line compiler installed.
The free version works and was used to create both {\f1\fs20 .obj} files, i.e. {\i C++Builder Compiler (bcc compiler) free download} - as available from {\i Embarcadero} web site.
For native {\i Windows} @*64-bit@ applications (since {\i Delphi} XE2), an external {\f1\fs20 .dll} file is needed. Since there is no official {\i SQLite3} download for {\i Win64} yet, you can use the one we supply at @http://synopse.info/files/SQLite3-64.7z
For FPC, you need to download both {\f1\fs20 Win32} and {\i Linux 32} {\f1\fs20 .o} files from @http://synopse.info/files/sqlite3fpc.7z then uncompress both embedded folders at the {\i mORMot} root folder (i.e. where {\f1\fs20 Synopse.inc} or {\f1\fs20 SynCommons.pas} stay). Those static files have been patched to support optional encryption of the {\i SQLite3} database file. Then enable the {\f1\fs20 FPCSQLITE3STATIC} conditional in your project, or directly modify {\f1\fs20 Synopse.inc} to include it, so that those {\f1\fs20 .o} files will be statically linked to the executable.
For FPC, you need to download static {\f1\fs20 .o} files from @http://synopse.info/files/sqlite3fpc.7z then uncompress all embedded folders at the {\i mORMot} root folder (i.e. where {\f1\fs20 Synopse.inc} and {\f1\fs20 SynCommons.pas} stay). Those static files have been patched to support optional encryption of the {\i SQLite3} database file. Then enable the {\f1\fs20 FPCSQLITE3STATIC} conditional in your project, or directly modify {\f1\fs20 Synopse.inc} to include it, so that those {\f1\fs20 .o} files will be statically linked to the executable.
You could also compile the static libraries from the {\f1\fs20 sqlite3.c} source, to run with FPC - do not forget to enable the {\f1\fs20 FPCSQLITE3STATIC} conditional in this case also.\line Under {\i Windows}, ensure the {\i MinGW} compiler is installed, then execute {\f1\fs20 c-fpcmingw.bat} from the {\i SQLite3} folder. It will create the {\f1\fs20 sqlite3.o} and {\f1\fs20 sqlite3fts.o} files, as expected by FPC.\line Under {\i @*Linux@}, Use the {\f1\fs20 c-fpcgcclin.sh} bash script.
: SpiderMonkey library
To enable {\i @*JavaScript@} support in {\i mORmot}, we rely on our version of the {\i @*SpiderMonkey@} library. See @79@.
@@ -460,8 +460,6 @@ function ECCCommand(cmd: TECCCommand; const sw: ICommandLine): TECCCommandError;
raise EECCException.Create('ECCCommand(nil)');
try
try
if not ecc_available then
raise EECCException.Create('ECC is not implemented on this platform');
case cmd of
ecNew: begin
repeat
View
@@ -882,6 +882,10 @@ interface
// older compilers will fallback to signed Int64 values
// - anyway, consider using SortDynArrayQWord() to compare QWord values
// in a safe and efficient way, under a CPUX86
// - you may use UInt64 explicitly in your computation (like in SynEcc.pas),
// if you are sure that Delphi 6-2007 compiler handles your code as expected,
// but mORMot code will expect to use QWord for its internal process
// (e.g. ORM/SOA serialization)
{$ifdef FPC_OR_UNICODE}
QWord = UInt64;
{$else}
@@ -12406,6 +12410,9 @@ procedure crc512c(buf: PAnsiChar; len: cardinal; out crc: THash512);
procedure FillZero(var secret: RawByteString); overload;
{$ifdef HASINLINE}inline;{$endif} overload;
/// fast computation of two 64-bit unsigned integers into a 128-bit value
procedure mul64x64(const left, right: QWord; out product: THash128Rec);
type
/// the potential features, retrieved from an Intel CPU
// - see https://en.wikipedia.org/wiki/CPUID#EAX.3D1:_Processor_Info_and_Feature_Bits
@@ -34489,6 +34496,69 @@ procedure FillZero(var secret: RawByteString); overload;
FillcharFast(pointer(secret)^,length(secret),0);
end;
{$ifdef CPU32DELPHI}
procedure mul64(a,b: cardinal; out product64: QWord);
asm // Delphi is not efficient for x86 target with QWord -> optimize
imul edx
mov [ecx], eax
mov [ecx + 4], edx
end;
{$endif}
procedure mul64x64(const left, right: QWord; out product: THash128Rec);
{$ifdef CPUX86}
asm // adapted from FPC compiler output, which is much better than Delphi's here
mov ecx, eax
mov eax, dword ptr [ebp+8H]
mul dword ptr [ebp+10H]
mov dword ptr [ecx], eax
mov dword ptr [ebp-4H], edx
mov eax, dword ptr [ebp+8H]
mul dword ptr [ebp+14H]
add eax, dword ptr [ebp-4H]
adc edx, 0
mov dword ptr [ebp-10H], eax
mov dword ptr [ebp-0CH], edx
mov eax, dword ptr [ebp+0CH]
mul dword ptr [ebp+10H]
add eax, dword ptr [ebp-10H]
adc edx, 0
mov dword ptr [ecx+4H], eax
mov dword ptr [ebp-14H], edx
mov eax, dword ptr [ebp+0CH]
mul dword ptr [ebp+14H]
add eax, dword ptr [ebp-0CH]
adc edx, 0
add eax, dword ptr [ebp-14H]
adc edx, 0
mov dword ptr [ecx+8H], eax
mov dword ptr [ecx+0CH], edx
end;
{$else}
var l: TQWordRec absolute left;
r: TQWordRec absolute right;
t1,t2,t3: TQWordRec;
begin
{$ifdef CPU32DELPHI}
mul64(l.L,r.L,t1.V);
mul64(l.H,r.L,t2.V);
inc(t2.V,t1.H);
mul64(l.L,r.H,t3.V);
inc(t3.V,t2.L);
mul64(l.H,r.H,product.H);
inc(product.H,t2.H+t3.H);
product.c0 := t1.L;
product.c1 := t3.V;
{$else}
t1.V := QWord(l.L)*r.L;
t2.V := QWord(l.H)*r.L+t1.H;
t3.V := QWord(l.L)*r.H+t2.L;
product.H := QWord(l.H)*r.H+t2.H+t3.H;
product.L := t3.V shl 32 or t1.L;
{$endif}
end;
{$endif}
procedure SymmetricEncrypt(key: cardinal; var data: RawByteString);
var i,len: integer;
d: PCardinal;
Oops, something went wrong.

0 comments on commit bc405cf

Please sign in to comment.