├── .gitattributes
├── .gitignore
├── CSPRNG.Delphi.groupproj
├── README.md
├── sample
├── CSPRNG_FMX.dpr
├── CSPRNG_FMX.dproj
├── CSPRNG_FMX.res
├── CSPRNG_FMX_Main.fmx
├── CSPRNG_FMX_Main.pas
├── CSPRNG_sample.dpr
├── CSPRNG_sample.dproj
└── CSPRNG_sample.res
├── src
├── CSPRNG.Interfaces.pas
├── CSPRNG.Provider.Base.pas
├── CSPRNG.Provider.MacOS64.pas
├── CSPRNG.Provider.Posix.pas
├── CSPRNG.Provider.Windows.pas
├── CSPRNG.Provider.iOS.pas
├── CSPRNG.pas
├── CSPRNG_sample.dpr
├── CSPRNG_sample.dproj
└── CSPRNG_sample.res
└── tests
├── CSPRNG.Tests.Providers.pas
├── CSPRNG.Tests.dpr
├── CSPRNG.Tests.dproj
├── CSPRNG.Tests.res
├── Win32
└── Debug
│ ├── TestInsightSettings.ini
│ └── dunitx-results.xml
└── Win64
└── Debug
└── dunitx-results.xml
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Set the default behavior, in case people don't have core.autocrlf set.
2 | #* binary
3 |
4 | # Core files that needs lf ending
5 | *.gitattributes text eol=lf diff
6 | *.gitignore text eol=lf diff
7 |
8 | # Declare text files that will always have CRLF line endings on checkout
9 | *.txt text eol=crlf diff
10 | *.md text eol=crlf diff
11 | *.xml text eol=crlf diff
12 | *.json text eol=crlf diff
13 | *.manifest text eol=crlf diff
14 | *.rc text eol=crlf diff
15 | *.bat text eol=crlf diff
16 |
17 | # Delphi specific text files that will always have CRLF line endings on checkout
18 | *.pas text eol=crlf diff
19 | *.inc text eol=crlf diff
20 | *.dfm text eol=crlf diff
21 | *.fmx text eol=crlf diff
22 | *.dpr text eol=crlf diff
23 | *.dpk text eol=crlf diff
24 | *.dproj text eol=crlf diff
25 | *.groupproj text eol=crlf diff
26 | *.deployproj text eol=crlf diff
27 | *.plist text eol=lf diff
28 |
29 | # Misc text files that will always have CRLF line endings on checkout
30 | *.cpp text eol=crlf diff
31 | *.h text eol=crlf diff
32 | *.hpp text eol=crlf diff
33 | *.asm text eol=crlf diff
34 | *.ps1 text eol=crlf diff
35 | *.prjmgc text eol=crlf diff
36 | *.sql text eol=crlf diff
37 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Uncomment these types if you want even more clean repository. But be careful.
2 | # It can make harm to an existing project source. Read explanations below.
3 | #
4 | # Resource files are binaries containing manifest, project icon and version info.
5 | # They can not be viewed as text or compared by diff-tools. Consider replacing them with .rc files.
6 | #*.res
7 | #
8 | # Type library file (binary). In old Delphi versions it should be stored.
9 | # Since Delphi 2009 it is produced from .ridl file and can safely be ignored.
10 | #*.tlb
11 | #
12 | # Diagram Portfolio file. Used by the diagram editor up to Delphi 7.
13 | # Uncomment this if you are not using diagrams or use newer Delphi version.
14 | #*.ddp
15 | #
16 | # Visual LiveBindings file. Added in Delphi XE2.
17 | # Uncomment this if you are not using LiveBindings Designer.
18 | #*.vlb
19 | #
20 | # Deployment Manager configuration file for your project. Added in Delphi XE2.
21 | # Uncomment this if it is not mobile development and you do not use remote debug feature.
22 | #*.deployproj
23 | #
24 | # C++ object files produced when C/C++ Output file generation is configured.
25 | # Uncomment this if you are not using external objects (zlib library for example).
26 | #*.obj
27 | #
28 |
29 | # Delphi compiler-generated binaries (safe to delete)
30 | *.exe
31 | *.dll
32 | *.bpl
33 | *.bpi
34 | *.dcp
35 | *.so
36 | *.apk
37 | *.drc
38 | *.map
39 | *.dres
40 | *.rsm
41 | *.tds
42 | *.dcu
43 | *.lib
44 | *.a
45 | *.o
46 | *.ocx
47 |
48 | # Delphi autogenerated files (duplicated info)
49 | *.cfg
50 | *.hpp
51 | *Resource.rc
52 | *.res
53 |
54 | # Delphi local files (user-specific info)
55 | *.local
56 | *.identcache
57 | *.projdata
58 | *.tvsconfig
59 | *.dsk
60 |
61 | # Delphi history and backups
62 | __history/
63 | __recovery/
64 | *.~*
65 |
66 | # Castalia statistics file (since XE7 Castalia is distributed with Delphi)
67 | *.stat
68 |
69 | # Boss dependency manager vendor folder https://github.com/HashLoad/boss
70 | modules/
71 |
72 | # Build folders
73 | **/Debug/
74 | **/Relase/
75 |
76 | AndroidManifest.template.xml
77 | *.deployproj
78 | *.res
79 |
--------------------------------------------------------------------------------
/CSPRNG.Delphi.groupproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | {979A6A91-DCB4-482C-AC19-E7D9A41B18D6}
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | Default.Personality.12
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # [DelphiCSPRNG](https://github.com/jimmckeeth/DelphiCSPRNG)
2 | _A cross-platform Cryptographically-Secure Pseudo-Random Number Generator for Delphi_
3 |
4 | I wanted an easy to use cross-platform random number generator that was more reliable than the built in Random. It is modular so you can just include the parts you want. Makes use of the platform secure random provider for each platform, with a common provider interface. I've only tested it on Win32, Win64, Android64, and Linux64.
5 |
6 | There are some basic tests and a sample app. Open to feedback, [issues](https://github.com/jimmckeeth/DelphiCSPRNG/issue) reports, and [pull requests](https://github.com/jimmckeeth/DelphiCSPRNG/fork). Especially if you want to test it on Apple hardware.
7 |
8 | **Disclaimer**: _Make sure you understand any code before using it for anything important._ Just because I am calling this "Cryptographically-Secure" doesn't necessarily mean it is secure or suitable for cryptography.
9 |
10 | ## Basic usage
11 |
12 | ```Delphi
13 | uses CSPRNG, CSPRNG.Interfaces;
14 |
15 | ///
16 | var rng: ICSPRNGProvider := GetCSPRNGProvider;
17 | Writeln(rng.GetFloat);
18 | Writeln(rng.GetUInt64);
19 | Writeln(rng.GetBase64);
20 | ```
21 |
22 | ## The provider interface
23 |
24 | ```Delphi
25 | type
26 | ICSPRNGProvider = interface
27 | // Generates a specified number of cryptographically secure random bytes.
28 | function GetBytes(const Count: Integer): TBytes;
29 |
30 | // Generates a cryptographically secure random unsigned 32-bit integer.
31 | function GetUInt32(const max: UInt32 = High(UInt32)): UInt32;
32 |
33 | // Generates a cryptographically secure random signed 32-bit integer.
34 | function GetInt32(const max: Int32 = High(Int32)): Int32;
35 |
36 | // Generates a cryptographically secure random signed 64-bit integer.
37 | function GetInt64(const max: Int64 = High(Int64)): Int64;
38 |
39 | // Generates a cryptographically secure random unsigned 64-bit integer.
40 | function GetUInt64(const max: UInt64 = High(UInt64)): UInt64;
41 |
42 | // Generates a cryptographically secure random float between 0 and 1
43 | function GetFloat: Double;
44 |
45 | // Generates a BASE64 encoded random string
46 | function GetBase64(const len: Integer = 1024): String;
47 | end;
48 | ```
49 |
50 | Most of the functionality comes from the base implementation, with the platform specific implementation providing the **`GetBytes`** function.
51 |
--------------------------------------------------------------------------------
/sample/CSPRNG_FMX.dpr:
--------------------------------------------------------------------------------
1 | program CSPRNG_FMX;
2 |
3 | uses
4 | System.StartUpCopy,
5 | FMX.Forms,
6 | CSPRNG_FMX_Main in 'CSPRNG_FMX_Main.pas' {Form28};
7 |
8 | {$R *.res}
9 |
10 | begin
11 | Application.Initialize;
12 | Application.CreateForm(TForm28, Form28);
13 | Application.Run;
14 | end.
15 |
--------------------------------------------------------------------------------
/sample/CSPRNG_FMX.dproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | True
4 | Application
5 | Debug
6 | FMX
7 | CSPRNG_FMX.dpr
8 | Win32
9 | {152D4698-4EAC-4079-9777-B9318D4E12A3}
10 | CSPRNG_FMX
11 | 20.2
12 | 693267
13 |
14 |
15 | true
16 |
17 |
18 | true
19 | Base
20 | true
21 |
22 |
23 | true
24 | Base
25 | true
26 |
27 |
28 | true
29 | Base
30 | true
31 |
32 |
33 | true
34 | Base
35 | true
36 |
37 |
38 | true
39 | Base
40 | true
41 |
42 |
43 | true
44 | Base
45 | true
46 |
47 |
48 | true
49 | Base
50 | true
51 |
52 |
53 | true
54 | Base
55 | true
56 |
57 |
58 | true
59 | Base
60 | true
61 |
62 |
63 | true
64 | Cfg_1
65 | true
66 | true
67 |
68 |
69 | true
70 | Cfg_1
71 | true
72 | true
73 |
74 |
75 | true
76 | Base
77 | true
78 |
79 |
80 | true
81 | Cfg_2
82 | true
83 | true
84 |
85 |
86 | true
87 | Cfg_2
88 | true
89 | true
90 |
91 |
92 | CSPRNG_FMX
93 | true
94 | true
95 | true
96 | true
97 | true
98 | true
99 | true
100 | true
101 | .\$(Platform)\$(Config)
102 | .\$(Platform)\$(Config)
103 | System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace)
104 | ..\src;$(DCC_UnitSearchPath)
105 | $(BDS)\bin\delphi_PROJECTICNS.icns
106 | $(BDS)\bin\delphi_PROJECTICON.ico
107 |
108 |
109 | $(BDS)\bin\Artwork\Android\FM_AdaptiveIcon_Background.xml
110 | $(BDS)\bin\Artwork\Android\FM_AdaptiveIcon_Foreground.xml
111 | $(BDS)\bin\Artwork\Android\FM_AdaptiveIcon_Monochrome.xml
112 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_144x144.png
113 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png
114 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_36x36.png
115 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_48x48.png
116 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_72x72.png
117 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_96x96.png
118 | $(BDS)\bin\Artwork\Android\FM_NotificationIcon_24x24.png
119 | $(BDS)\bin\Artwork\Android\FM_NotificationIcon_36x36.png
120 | $(BDS)\bin\Artwork\Android\FM_NotificationIcon_48x48.png
121 | $(BDS)\bin\Artwork\Android\FM_NotificationIcon_72x72.png
122 | $(BDS)\bin\Artwork\Android\FM_NotificationIcon_96x96.png
123 | $(BDS)\bin\Artwork\Android\FM_SplashImage_426x320.png
124 | $(BDS)\bin\Artwork\Android\FM_SplashImage_470x320.png
125 | $(BDS)\bin\Artwork\Android\FM_SplashImage_640x480.png
126 | $(BDS)\bin\Artwork\Android\FM_SplashImage_960x720.png
127 | $(BDS)\bin\Artwork\Android\FM_VectorizedNotificationIcon.xml
128 | $(BDS)\bin\Artwork\Android\FM_VectorizedSplash.xml
129 | $(BDS)\bin\Artwork\Android\FM_VectorizedSplashDark.xml
130 | $(BDS)\bin\Artwork\Android\FM_VectorizedSplashV31.xml
131 | $(BDS)\bin\Artwork\Android\FM_VectorizedSplashV31Dark.xml
132 | Debug
133 | fmx;DbxCommonDriver;bindengine;IndyIPCommon;emsclient;IndyProtocols;dbxcds;FmxTeeUI;FireDACSqliteDriver;DbxClientDriver;soapmidas;dbexpress;inet;FireDACDBXDriver;CustomIPTransport;IndySystem;FireDACCommon;emsserverresource;bindcompdbx;rtl;DBXSqliteDriver;DataSnapFireDAC;FireDAC;xmlrtl;dsnap;DataSnapNativeClient;emshosting;FireDACCommonDriver;IndyIPClient;emsedge;bindcompfmx;fmxFireDAC;DataSnapCommon;fmxase;dbrtl;DBXInterBaseDriver;bindcomp;inetstn;IndyCore;RESTBackendComponents;AWSSDKFMX;RESTComponents;IndyIPServer;dsnapxml;DataSnapClient;DataSnapProviderClient;emsclientfiredac;FireDACDSDriver;tethering;CloudService;FMXTee;soaprtl;soapserver;FireDACIBDriver;$(DCC_UsePackage)
134 | activity-1.7.2.dex.jar;annotation-experimental-1.3.0.dex.jar;annotation-jvm-1.6.0.dex.jar;annotations-13.0.dex.jar;appcompat-1.2.0.dex.jar;appcompat-resources-1.2.0.dex.jar;billing-6.0.1.dex.jar;biometric-1.1.0.dex.jar;browser-1.4.0.dex.jar;cloud-messaging.dex.jar;collection-1.1.0.dex.jar;concurrent-futures-1.1.0.dex.jar;core-1.10.1.dex.jar;core-common-2.2.0.dex.jar;core-ktx-1.10.1.dex.jar;core-runtime-2.2.0.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;error_prone_annotations-2.9.0.dex.jar;exifinterface-1.3.6.dex.jar;firebase-annotations-16.2.0.dex.jar;firebase-common-20.3.1.dex.jar;firebase-components-17.1.0.dex.jar;firebase-datatransport-18.1.7.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-encoders-proto-16.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.1.3.dex.jar;firebase-installations-interop-17.1.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-23.1.2.dex.jar;fmx.dex.jar;fragment-1.2.5.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;kotlin-stdlib-1.8.22.dex.jar;kotlin-stdlib-common-1.8.22.dex.jar;kotlin-stdlib-jdk7-1.8.22.dex.jar;kotlin-stdlib-jdk8-1.8.22.dex.jar;kotlinx-coroutines-android-1.6.4.dex.jar;kotlinx-coroutines-core-jvm-1.6.4.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.6.1.dex.jar;lifecycle-livedata-2.6.1.dex.jar;lifecycle-livedata-core-2.6.1.dex.jar;lifecycle-runtime-2.6.1.dex.jar;lifecycle-service-2.6.1.dex.jar;lifecycle-viewmodel-2.6.1.dex.jar;lifecycle-viewmodel-savedstate-2.6.1.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;okio-jvm-3.4.0.dex.jar;play-services-ads-22.2.0.dex.jar;play-services-ads-base-22.2.0.dex.jar;play-services-ads-identifier-18.0.0.dex.jar;play-services-ads-lite-22.2.0.dex.jar;play-services-appset-16.0.1.dex.jar;play-services-base-18.1.0.dex.jar;play-services-basement-18.1.0.dex.jar;play-services-cloud-messaging-17.0.1.dex.jar;play-services-location-21.0.1.dex.jar;play-services-maps-18.1.0.dex.jar;play-services-measurement-base-20.1.2.dex.jar;play-services-measurement-sdk-api-20.1.2.dex.jar;play-services-stats-17.0.2.dex.jar;play-services-tasks-18.0.2.dex.jar;print-1.0.0.dex.jar;profileinstaller-1.3.0.dex.jar;room-common-2.2.5.dex.jar;room-runtime-2.2.5.dex.jar;savedstate-1.2.1.dex.jar;sqlite-2.1.0.dex.jar;sqlite-framework-2.1.0.dex.jar;startup-runtime-1.1.1.dex.jar;tracing-1.0.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.1.8.dex.jar;transport-runtime-3.1.8.dex.jar;user-messaging-platform-2.0.0.dex.jar;vectordrawable-1.1.0.dex.jar;vectordrawable-animated-1.1.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.7.0.dex.jar
135 | true
136 | false
137 | true
138 | true
139 | true
140 | package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey=;minSdkVersion=23;targetSdkVersion=34
141 |
142 |
143 | $(BDS)\bin\Artwork\Android\FM_AdaptiveIcon_Background.xml
144 | $(BDS)\bin\Artwork\Android\FM_AdaptiveIcon_Foreground.xml
145 | $(BDS)\bin\Artwork\Android\FM_AdaptiveIcon_Monochrome.xml
146 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_144x144.png
147 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_192x192.png
148 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_36x36.png
149 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_48x48.png
150 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_72x72.png
151 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_96x96.png
152 | $(BDS)\bin\Artwork\Android\FM_NotificationIcon_24x24.png
153 | $(BDS)\bin\Artwork\Android\FM_NotificationIcon_36x36.png
154 | $(BDS)\bin\Artwork\Android\FM_NotificationIcon_48x48.png
155 | $(BDS)\bin\Artwork\Android\FM_NotificationIcon_72x72.png
156 | $(BDS)\bin\Artwork\Android\FM_NotificationIcon_96x96.png
157 | $(BDS)\bin\Artwork\Android\FM_SplashImage_426x320.png
158 | $(BDS)\bin\Artwork\Android\FM_SplashImage_470x320.png
159 | $(BDS)\bin\Artwork\Android\FM_SplashImage_640x480.png
160 | $(BDS)\bin\Artwork\Android\FM_SplashImage_960x720.png
161 | $(BDS)\bin\Artwork\Android\FM_VectorizedNotificationIcon.xml
162 | $(BDS)\bin\Artwork\Android\FM_VectorizedSplash.xml
163 | $(BDS)\bin\Artwork\Android\FM_VectorizedSplashDark.xml
164 | $(BDS)\bin\Artwork\Android\FM_VectorizedSplashV31.xml
165 | $(BDS)\bin\Artwork\Android\FM_VectorizedSplashV31Dark.xml
166 | Debug
167 | fmx;DbxCommonDriver;bindengine;IndyIPCommon;emsclient;IndyProtocols;dbxcds;FmxTeeUI;FireDACSqliteDriver;DbxClientDriver;soapmidas;dbexpress;inet;FireDACDBXDriver;CustomIPTransport;IndySystem;FireDACCommon;emsserverresource;bindcompdbx;rtl;DBXSqliteDriver;DataSnapFireDAC;FireDAC;xmlrtl;dsnap;DataSnapNativeClient;emshosting;FireDACCommonDriver;IndyIPClient;emsedge;bindcompfmx;fmxFireDAC;DataSnapCommon;dbrtl;DBXInterBaseDriver;bindcomp;inetstn;IndyCore;RESTBackendComponents;AWSSDKFMX;RESTComponents;IndyIPServer;dsnapxml;DataSnapClient;DataSnapProviderClient;emsclientfiredac;FireDACDSDriver;tethering;CloudService;FMXTee;soaprtl;soapserver;FireDACIBDriver;$(DCC_UsePackage)
168 | activity-1.7.2.dex.jar;annotation-experimental-1.3.0.dex.jar;annotation-jvm-1.6.0.dex.jar;annotations-13.0.dex.jar;appcompat-1.2.0.dex.jar;appcompat-resources-1.2.0.dex.jar;billing-6.0.1.dex.jar;biometric-1.1.0.dex.jar;browser-1.4.0.dex.jar;cloud-messaging.dex.jar;collection-1.1.0.dex.jar;concurrent-futures-1.1.0.dex.jar;core-1.10.1.dex.jar;core-common-2.2.0.dex.jar;core-ktx-1.10.1.dex.jar;core-runtime-2.2.0.dex.jar;cursoradapter-1.0.0.dex.jar;customview-1.0.0.dex.jar;documentfile-1.0.0.dex.jar;drawerlayout-1.0.0.dex.jar;error_prone_annotations-2.9.0.dex.jar;exifinterface-1.3.6.dex.jar;firebase-annotations-16.2.0.dex.jar;firebase-common-20.3.1.dex.jar;firebase-components-17.1.0.dex.jar;firebase-datatransport-18.1.7.dex.jar;firebase-encoders-17.0.0.dex.jar;firebase-encoders-json-18.0.0.dex.jar;firebase-encoders-proto-16.0.0.dex.jar;firebase-iid-interop-17.1.0.dex.jar;firebase-installations-17.1.3.dex.jar;firebase-installations-interop-17.1.0.dex.jar;firebase-measurement-connector-19.0.0.dex.jar;firebase-messaging-23.1.2.dex.jar;fmx.dex.jar;fragment-1.2.5.dex.jar;google-play-licensing.dex.jar;interpolator-1.0.0.dex.jar;javax.inject-1.dex.jar;kotlin-stdlib-1.8.22.dex.jar;kotlin-stdlib-common-1.8.22.dex.jar;kotlin-stdlib-jdk7-1.8.22.dex.jar;kotlin-stdlib-jdk8-1.8.22.dex.jar;kotlinx-coroutines-android-1.6.4.dex.jar;kotlinx-coroutines-core-jvm-1.6.4.dex.jar;legacy-support-core-utils-1.0.0.dex.jar;lifecycle-common-2.6.1.dex.jar;lifecycle-livedata-2.6.1.dex.jar;lifecycle-livedata-core-2.6.1.dex.jar;lifecycle-runtime-2.6.1.dex.jar;lifecycle-service-2.6.1.dex.jar;lifecycle-viewmodel-2.6.1.dex.jar;lifecycle-viewmodel-savedstate-2.6.1.dex.jar;listenablefuture-1.0.dex.jar;loader-1.0.0.dex.jar;localbroadcastmanager-1.0.0.dex.jar;okio-jvm-3.4.0.dex.jar;play-services-ads-22.2.0.dex.jar;play-services-ads-base-22.2.0.dex.jar;play-services-ads-identifier-18.0.0.dex.jar;play-services-ads-lite-22.2.0.dex.jar;play-services-appset-16.0.1.dex.jar;play-services-base-18.1.0.dex.jar;play-services-basement-18.1.0.dex.jar;play-services-cloud-messaging-17.0.1.dex.jar;play-services-location-21.0.1.dex.jar;play-services-maps-18.1.0.dex.jar;play-services-measurement-base-20.1.2.dex.jar;play-services-measurement-sdk-api-20.1.2.dex.jar;play-services-stats-17.0.2.dex.jar;play-services-tasks-18.0.2.dex.jar;print-1.0.0.dex.jar;profileinstaller-1.3.0.dex.jar;room-common-2.2.5.dex.jar;room-runtime-2.2.5.dex.jar;savedstate-1.2.1.dex.jar;sqlite-2.1.0.dex.jar;sqlite-framework-2.1.0.dex.jar;startup-runtime-1.1.1.dex.jar;tracing-1.0.0.dex.jar;transport-api-3.0.0.dex.jar;transport-backend-cct-3.1.8.dex.jar;transport-runtime-3.1.8.dex.jar;user-messaging-platform-2.0.0.dex.jar;vectordrawable-1.1.0.dex.jar;vectordrawable-animated-1.1.0.dex.jar;versionedparcelable-1.1.1.dex.jar;viewpager-1.0.0.dex.jar;work-runtime-2.7.0.dex.jar
169 | true
170 | false
171 | true
172 | true
173 | true
174 | package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey=;minSdkVersion=23;targetSdkVersion=34
175 |
176 |
177 | Debug
178 | DataSnapServer;fmx;DbxCommonDriver;bindengine;IndyIPCommon;FireDACCommonODBC;emsclient;IndyProtocols;dbxcds;FmxTeeUI;DBXFirebirdDriver;FireDACSqliteDriver;DbxClientDriver;soapmidas;dbexpress;inet;FireDACDBXDriver;fmxdae;CustomIPTransport;FireDACMSSQLDriver;IndySystem;FireDACCommon;DataSnapServerMidas;FireDACODBCDriver;emsserverresource;bindcompdbx;rtl;FireDACMySQLDriver;DBXSqliteDriver;DataSnapFireDAC;inetdbxpress;FireDAC;xmlrtl;dsnap;DBXOracleDriver;DBXInformixDriver;fmxobj;DataSnapNativeClient;emshosting;FireDACCommonDriver;IndyIPClient;emsedge;bindcompfmx;inetdb;FireDACASADriver;fmxFireDAC;DBXMySQLDriver;DataSnapCommon;fmxase;dbrtl;FireDACOracleDriver;DataSnapIndy10ServerTransport;DBXInterBaseDriver;FireDACMongoDBDriver;FireDACTDataDriver;bindcomp;inetstn;IndyCore;RESTBackendComponents;AWSSDKFMX;RESTComponents;IndyIPServer;dsnapxml;DataSnapClient;DataSnapProviderClient;emsclientfiredac;FireDACPgDriver;FireDACDSDriver;tethering;CloudService;DBXSybaseASADriver;FMXTee;soaprtl;soapserver;FireDACIBDriver;$(DCC_UsePackage)
179 | true
180 | CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundleShortVersionString=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities;NSLocationUsageDescription=The reason for accessing the location information of the user;NSContactsUsageDescription=The reason for accessing the contacts;NSCalendarsUsageDescription=The reason for accessing the calendar data;NSRemindersUsageDescription=The reason for accessing the reminders;NSCameraUsageDescription=The reason for accessing the camera;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSMotionUsageDescription=The reason for accessing the accelerometer;NSDesktopFolderUsageDescription=The reason for accessing the Desktop folder;NSDocumentsFolderUsageDescription=The reason for accessing the Documents folder;NSDownloadsFolderUsageDescription=The reason for accessing the Downloads folder;NSNetworkVolumesUsageDescription=The reason for accessing files on a network volume;NSRemovableVolumesUsageDescription=The reason for accessing files on a removable volume;NSSpeechRecognitionUsageDescription=The reason for requesting to send user data to Apple's speech recognition servers;ITSAppUsesNonExemptEncryption=false;NSBluetoothAlwaysUsageDescription=The reason for accessing the Bluetooth interface
181 |
182 |
183 | Debug
184 | DataSnapServer;fmx;DbxCommonDriver;bindengine;IndyIPCommon;FireDACCommonODBC;emsclient;IndyProtocols;dbxcds;FmxTeeUI;DBXFirebirdDriver;FireDACSqliteDriver;DbxClientDriver;soapmidas;dbexpress;inet;FireDACDBXDriver;fmxdae;CustomIPTransport;FireDACMSSQLDriver;IndySystem;FireDACCommon;DataSnapServerMidas;FireDACODBCDriver;emsserverresource;bindcompdbx;rtl;FireDACMySQLDriver;DBXSqliteDriver;DataSnapFireDAC;inetdbxpress;FireDAC;xmlrtl;dsnap;DBXOracleDriver;DBXInformixDriver;fmxobj;DataSnapNativeClient;emshosting;FireDACCommonDriver;IndyIPClient;emsedge;bindcompfmx;inetdb;FireDACASADriver;fmxFireDAC;DBXMySQLDriver;DataSnapCommon;fmxase;dbrtl;FireDACOracleDriver;DataSnapIndy10ServerTransport;DBXInterBaseDriver;FireDACMongoDBDriver;FireDACTDataDriver;bindcomp;inetstn;IndyCore;RESTBackendComponents;AWSSDKFMX;RESTComponents;IndyIPServer;dsnapxml;DataSnapClient;DataSnapProviderClient;emsclientfiredac;FireDACPgDriver;FireDACDSDriver;tethering;CloudService;DBXSybaseASADriver;FMXTee;soaprtl;soapserver;FireDACIBDriver;$(DCC_UsePackage)
185 | true
186 | CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundleShortVersionString=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities;NSLocationUsageDescription=The reason for accessing the location information of the user;NSContactsUsageDescription=The reason for accessing the contacts;NSCalendarsUsageDescription=The reason for accessing the calendar data;NSRemindersUsageDescription=The reason for accessing the reminders;NSCameraUsageDescription=The reason for accessing the camera;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSMotionUsageDescription=The reason for accessing the accelerometer;NSDesktopFolderUsageDescription=The reason for accessing the Desktop folder;NSDocumentsFolderUsageDescription=The reason for accessing the Documents folder;NSDownloadsFolderUsageDescription=The reason for accessing the Downloads folder;NSNetworkVolumesUsageDescription=The reason for accessing files on a network volume;NSRemovableVolumesUsageDescription=The reason for accessing files on a removable volume;NSSpeechRecognitionUsageDescription=The reason for requesting to send user data to Apple's speech recognition servers;ITSAppUsesNonExemptEncryption=false;NSBluetoothAlwaysUsageDescription=The reason for accessing the Bluetooth interface
187 |
188 |
189 | Debug
190 | Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)
191 | RaizeComponentsVcl;vclwinx;DataSnapServer;P4DPandas;fmx;vclie;DbxCommonDriver;bindengine;IndyIPCommon;VCLRESTComponents;DBXMSSQLDriver;FireDACCommonODBC;emsclient;appanalytics;IndyProtocols;vclx;Skia.Package.RTL;dbxcds;vcledge;FmxTeeUI;P4DONNXRuntime;DBXFirebirdDriver;FireDACSqliteDriver;DbxClientDriver;GdkToolsApiHelper;FMXColorEditors;soapmidas;JclVcl;TeeUI;Jcl;dbexpress;Python;FormGuardPkg;inet;PythonVcl;vcltouch;P4DOpenCV;FireDACDBXDriver;fmxdae;CustomIPTransport;FireDACMSSQLDriver;P4DSciPy;IndySystem;CodolexUtils;BossExperts;CodolexEditors;VirtualTreesR;JclContainers;vclFireDAC;FireDACCommon;DataSnapServerMidas;FireDACODBCDriver;emsserverresource;DOSCommandDR;P4DScikitLearn;P4DPyTorch;bindcompdbx;rtl;FireDACMySQLDriver;DBXSqliteDriver;DBXSybaseASEDriver;vclimg;DataSnapFireDAC;inetdbxpress;FireDAC;xmlrtl;P4DEnvironment;dsnap;FireDACDb2Driver;DBXOracleDriver;DBXInformixDriver;fmxobj;bindcompvclsmp;DataSnapNativeClient;DatasnapConnectorsFreePascal;P4DMatplotLib;emshosting;FireDACCommonDriver;IndyIPClient;bindcompvclwinx;emsedge;bindcompfmx;inetdb;FireDACASADriver;CodolexComponents;Tee;vclactnband;fmxFireDAC;FireDACInfxDriver;P4DPyPackage;DBXMySQLDriver;VclSmp;DataSnapCommon;CodolexFramework;fmxase;DBXOdbcDriver;dbrtl;FireDACOracleDriver;Skia.Package.FMX;CodeSiteExpressPkg;TeeDB;FireDACMSAccDriver;DataSnapIndy10ServerTransport;JclDeveloperTools;P4DTensorFlow;DataSnapConnectors;P4DKeras;vcldsnap;DBXInterBaseDriver;CodolexSynEditDR;FireDACMongoDBDriver;CodolexCodeGenInterfaces;FireDACTDataDriver;Skia.Package.VCL;vcldb;CodolexRenderingVCL;SynEditDR;bindcomp;inetstn;IndyCore;RESTBackendComponents;AWSSDKFMX;FireDACADSDriver;RaizeComponentsVclDb;AWSSDKVCL;RESTComponents;IndyIPServer;vcl;dsnapxml;adortl;dsnapcon;DataSnapClient;DataSnapProviderClient;P4DNLTK;FixInsight_12;DBXDb2Driver;emsclientfiredac;FireDACPgDriver;FireDACDSDriver;tethering;bindcompvcl;CodolexCore;CloudService;DBXSybaseASADriver;P4DNumPy;FMXTee;PythonFmx;soaprtl;soapserver;FireDACIBDriver;$(DCC_UsePackage)
192 | $(BDS)\bin\default_app.manifest
193 | $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png
194 | $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png
195 | true
196 | CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=
197 | 1033
198 |
199 |
200 | Debug
201 | Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace)
202 | RaizeComponentsVcl;vclwinx;DataSnapServer;fmx;vclie;DbxCommonDriver;bindengine;IndyIPCommon;VCLRESTComponents;DBXMSSQLDriver;FireDACCommonODBC;emsclient;appanalytics;IndyProtocols;vclx;dbxcds;vcledge;FmxTeeUI;DBXFirebirdDriver;FireDACSqliteDriver;DbxClientDriver;soapmidas;TeeUI;dbexpress;inet;PythonVcl;vcltouch;FireDACDBXDriver;fmxdae;CustomIPTransport;FireDACMSSQLDriver;IndySystem;VirtualTreesR;vclFireDAC;FireDACCommon;DataSnapServerMidas;FireDACODBCDriver;emsserverresource;DOSCommandDR;bindcompdbx;rtl;FireDACMySQLDriver;DBXSqliteDriver;DBXSybaseASEDriver;vclimg;DataSnapFireDAC;inetdbxpress;FireDAC;xmlrtl;dsnap;FireDACDb2Driver;DBXOracleDriver;DBXInformixDriver;fmxobj;bindcompvclsmp;DataSnapNativeClient;DatasnapConnectorsFreePascal;emshosting;FireDACCommonDriver;IndyIPClient;bindcompvclwinx;emsedge;bindcompfmx;inetdb;FireDACASADriver;Tee;vclactnband;fmxFireDAC;FireDACInfxDriver;DBXMySQLDriver;VclSmp;DataSnapCommon;fmxase;DBXOdbcDriver;dbrtl;FireDACOracleDriver;TeeDB;FireDACMSAccDriver;DataSnapIndy10ServerTransport;DataSnapConnectors;vcldsnap;DBXInterBaseDriver;FireDACMongoDBDriver;FireDACTDataDriver;Skia.Package.VCL;vcldb;SynEditDR;bindcomp;inetstn;IndyCore;RESTBackendComponents;AWSSDKFMX;FireDACADSDriver;RaizeComponentsVclDb;AWSSDKVCL;RESTComponents;IndyIPServer;vcl;dsnapxml;adortl;dsnapcon;DataSnapClient;DataSnapProviderClient;DBXDb2Driver;emsclientfiredac;FireDACPgDriver;FireDACDSDriver;tethering;bindcompvcl;CloudService;DBXSybaseASADriver;FMXTee;soaprtl;soapserver;FireDACIBDriver;$(DCC_UsePackage)
203 | $(BDS)\bin\default_app.manifest
204 | $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png
205 | $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png
206 | true
207 | CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=
208 | 1033
209 |
210 |
211 | Debug
212 | fmx;DbxCommonDriver;bindengine;IndyIPCommon;emsclient;IndyProtocols;dbxcds;FmxTeeUI;FireDACSqliteDriver;DbxClientDriver;soapmidas;dbexpress;inet;FireDACDBXDriver;CustomIPTransport;IndySystem;FireDACCommon;emsserverresource;bindcompdbx;rtl;DBXSqliteDriver;DataSnapFireDAC;FireDAC;xmlrtl;dsnap;DataSnapNativeClient;emshosting;FireDACCommonDriver;IndyIPClient;emsedge;bindcompfmx;fmxFireDAC;DataSnapCommon;fmxase;dbrtl;DBXInterBaseDriver;bindcomp;inetstn;IndyCore;RESTBackendComponents;AWSSDKFMX;RESTComponents;IndyIPServer;dsnapxml;DataSnapClient;DataSnapProviderClient;emsclientfiredac;FireDACDSDriver;tethering;CloudService;FMXTee;soaprtl;soapserver;FireDACIBDriver;$(DCC_UsePackage)
213 | $(MSBuildProjectName)
214 | true
215 | CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0;CFBundleShortVersionString=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;NSLocationAlwaysAndWhenInUseUsageDescription=The reason for accessing the location information of the user;UIBackgroundModes=;NSContactsUsageDescription=The reason for accessing the contacts;NSPhotoLibraryUsageDescription=The reason for accessing the photo library;NSPhotoLibraryAddUsageDescription=The reason for adding to the photo library;NSCameraUsageDescription=The reason for accessing the camera;NSFaceIDUsageDescription=The reason for accessing the face id;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSSiriUsageDescription=The reason for accessing Siri;ITSAppUsesNonExemptEncryption=false;NSBluetoothAlwaysUsageDescription=The reason for accessing bluetooth;NSBluetoothPeripheralUsageDescription=The reason for accessing bluetooth peripherals;NSCalendarsUsageDescription=The reason for accessing the calendar data;NSRemindersUsageDescription=The reason for accessing the reminders;NSMotionUsageDescription=The reason for accessing the accelerometer;NSSpeechRecognitionUsageDescription=The reason for requesting to send user data to Apple's speech recognition servers
216 | iPhoneAndiPad
217 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_1024x1024.png
218 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_152x152.png
219 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_167x167.png
220 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImage_2x.png
221 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageDark_2x.png
222 | $(BDS)\bin\Artwork\iOS\iPad\FM_NotificationIcon_40x40.png
223 | $(BDS)\bin\Artwork\iOS\iPad\FM_SettingIcon_58x58.png
224 | $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_80x80.png
225 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_120x120.png
226 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_180x180.png
227 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_2x.png
228 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_3x.png
229 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImageDark_2x.png
230 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImageDark_3x.png
231 | $(BDS)\bin\Artwork\iOS\iPhone\FM_NotificationIcon_40x40.png
232 | $(BDS)\bin\Artwork\iOS\iPhone\FM_NotificationIcon_60x60.png
233 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SettingIcon_58x58.png
234 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SettingIcon_87x87.png
235 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_120x120.png
236 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_80x80.png
237 |
238 |
239 | fmx;DbxCommonDriver;bindengine;IndyIPCommon;emsclient;IndyProtocols;dbxcds;FmxTeeUI;FireDACSqliteDriver;DbxClientDriver;soapmidas;dbexpress;inet;FireDACDBXDriver;CustomIPTransport;IndySystem;FireDACCommon;emsserverresource;bindcompdbx;rtl;DBXSqliteDriver;DataSnapFireDAC;FireDAC;xmlrtl;dsnap;DataSnapNativeClient;emshosting;FireDACCommonDriver;IndyIPClient;emsedge;bindcompfmx;fmxFireDAC;DataSnapCommon;fmxase;dbrtl;DBXInterBaseDriver;bindcomp;inetstn;IndyCore;RESTBackendComponents;AWSSDKFMX;RESTComponents;IndyIPServer;dsnapxml;DataSnapClient;DataSnapProviderClient;emsclientfiredac;FireDACDSDriver;tethering;CloudService;FMXTee;soaprtl;soapserver;FireDACIBDriver;$(DCC_UsePackage)
240 | true
241 | CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0;CFBundleShortVersionString=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;NSLocationAlwaysAndWhenInUseUsageDescription=The reason for accessing the location information of the user;UIBackgroundModes=;NSContactsUsageDescription=The reason for accessing the contacts;NSPhotoLibraryUsageDescription=The reason for accessing the photo library;NSPhotoLibraryAddUsageDescription=The reason for adding to the photo library;NSCameraUsageDescription=The reason for accessing the camera;NSFaceIDUsageDescription=The reason for accessing the face id;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSSiriUsageDescription=The reason for accessing Siri;ITSAppUsesNonExemptEncryption=false;NSBluetoothAlwaysUsageDescription=The reason for accessing bluetooth;NSBluetoothPeripheralUsageDescription=The reason for accessing bluetooth peripherals;NSCalendarsUsageDescription=The reason for accessing the calendar data;NSRemindersUsageDescription=The reason for accessing the reminders;NSMotionUsageDescription=The reason for accessing the accelerometer;NSSpeechRecognitionUsageDescription=The reason for requesting to send user data to Apple's speech recognition servers
242 | iPhoneAndiPad
243 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_1024x1024.png
244 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_152x152.png
245 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_167x167.png
246 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImage_2x.png
247 | $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageDark_2x.png
248 | $(BDS)\bin\Artwork\iOS\iPad\FM_NotificationIcon_40x40.png
249 | $(BDS)\bin\Artwork\iOS\iPad\FM_SettingIcon_58x58.png
250 | $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_80x80.png
251 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_120x120.png
252 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_180x180.png
253 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_2x.png
254 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImage_3x.png
255 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImageDark_2x.png
256 | $(BDS)\bin\Artwork\iOS\iPhone\FM_LaunchImageDark_3x.png
257 | $(BDS)\bin\Artwork\iOS\iPhone\FM_NotificationIcon_40x40.png
258 | $(BDS)\bin\Artwork\iOS\iPhone\FM_NotificationIcon_60x60.png
259 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SettingIcon_58x58.png
260 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SettingIcon_87x87.png
261 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_120x120.png
262 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_80x80.png
263 |
264 |
265 | true
266 | true
267 | DEBUG;$(DCC_Define)
268 | true
269 | true
270 | false
271 | true
272 | true
273 |
274 |
275 | PerMonitorV2
276 | false
277 | true
278 | 1033
279 |
280 |
281 | PerMonitorV2
282 |
283 |
284 | 0
285 | RELEASE;$(DCC_Define)
286 | false
287 | 0
288 |
289 |
290 | PerMonitorV2
291 |
292 |
293 | PerMonitorV2
294 |
295 |
296 |
297 | MainSource
298 |
299 |
300 |
301 | fmx
302 |
303 |
304 | Base
305 |
306 |
307 | Cfg_1
308 | Base
309 |
310 |
311 | Cfg_2
312 | Base
313 |
314 |
315 |
316 | Delphi.Personality.12
317 | Application
318 |
319 |
320 |
321 | CSPRNG_FMX.dpr
322 |
323 |
324 |
325 |
326 | True
327 | True
328 | False
329 | True
330 | True
331 | True
332 | True
333 | False
334 | True
335 | True
336 |
337 |
338 | 12
339 |
340 |
341 |
342 |
343 |
344 |
--------------------------------------------------------------------------------
/sample/CSPRNG_FMX.res:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimmckeeth/DelphiCSPRNG/f49d935b20d06f61fc18461c71b22da56da48dca/sample/CSPRNG_FMX.res
--------------------------------------------------------------------------------
/sample/CSPRNG_FMX_Main.fmx:
--------------------------------------------------------------------------------
1 | object Form28: TForm28
2 | Left = 0
3 | Top = 0
4 | Caption = 'Form28'
5 | ClientHeight = 480
6 | ClientWidth = 640
7 | FormFactor.Width = 320
8 | FormFactor.Height = 480
9 | FormFactor.Devices = [Desktop]
10 | OnCreate = FormCreate
11 | DesignerMasterStyle = 0
12 | object Button1: TButton
13 | Position.X = 8.000000000000000000
14 | Position.Y = 8.000000000000000000
15 | Size.Width = 80.000000000000000000
16 | Size.Height = 40.000000000000000000
17 | Size.PlatformDefault = False
18 | TabOrder = 0
19 | Text = 'Button1'
20 | TextSettings.Trimming = None
21 | OnClick = Button1Click
22 | end
23 | object Memo1: TMemo
24 | Touch.InteractiveGestures = [Pan, LongTap, DoubleTap]
25 | DataDetectorTypes = []
26 | ShowScrollBars = False
27 | TextSettings.WordWrap = True
28 | Anchors = [akLeft, akTop, akRight, akBottom]
29 | Position.X = 8.000000000000000000
30 | Position.Y = 56.000000000000000000
31 | Size.Width = 624.000000000000000000
32 | Size.Height = 416.000000000000000000
33 | Size.PlatformDefault = False
34 | TabOrder = 1
35 | Viewport.Width = 620.000000000000000000
36 | Viewport.Height = 412.000000000000000000
37 | end
38 | end
39 |
--------------------------------------------------------------------------------
/sample/CSPRNG_FMX_Main.pas:
--------------------------------------------------------------------------------
1 | unit CSPRNG_FMX_Main;
2 |
3 | interface
4 |
5 | uses
6 | System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
7 | FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
8 |
9 | CSPRNG, CSPRNG.Interfaces, FMX.Memo.Types, FMX.ScrollBox, FMX.Memo,
10 | FMX.Controls.Presentation, FMX.StdCtrls;
11 |
12 | type
13 | TForm28 = class(TForm)
14 | Button1: TButton;
15 | Memo1: TMemo;
16 | procedure FormCreate(Sender: TObject);
17 | procedure Button1Click(Sender: TObject);
18 | private
19 | { Private declarations }
20 | rng: ICSPRNGProvider;
21 | public
22 | { Public declarations }
23 | end;
24 |
25 | var
26 | Form28: TForm28;
27 |
28 | implementation
29 |
30 | {$R *.fmx}
31 |
32 | procedure TForm28.Button1Click(Sender: TObject);
33 | begin
34 | memo1.Lines.Text := rng.GetBase64()
35 | end;
36 |
37 | procedure TForm28.FormCreate(Sender: TObject);
38 | begin
39 | rng := GetCSPRNGProvider;
40 | end;
41 |
42 | end.
43 |
--------------------------------------------------------------------------------
/sample/CSPRNG_sample.dpr:
--------------------------------------------------------------------------------
1 | program CSPRNG_sample;
2 |
3 | {$APPTYPE CONSOLE}
4 |
5 | {$R *.res}
6 |
7 | uses
8 | System.SysUtils,
9 | CSPRNG in '..\src\CSPRNG.pas',
10 | CSPRNG.Interfaces in '..\src\CSPRNG.Interfaces.pas',
11 | CSPRNG.ProviderInfo in '..\src\CSPRNG.ProviderInfo.pas';
12 |
13 | begin
14 | try
15 | { TODO -oUser -cConsole Main : Insert code here }
16 | except
17 | on E: Exception do
18 | Writeln(E.ClassName, ': ', E.Message);
19 | end;
20 | end.
21 |
--------------------------------------------------------------------------------
/sample/CSPRNG_sample.dproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | True
4 | Console
5 | Debug
6 | None
7 | CSPRNG_sample.dpr
8 | Win32
9 | {7F7C03D2-1B62-4C4B-8FA9-C2EEB044296C}
10 | CSPRNG_sample
11 | 20.1
12 | 1
13 |
14 |
15 | true
16 |
17 |
18 | true
19 | Base
20 | true
21 |
22 |
23 | true
24 | Base
25 | true
26 |
27 |
28 | true
29 | Cfg_1
30 | true
31 | true
32 |
33 |
34 | true
35 | Base
36 | true
37 |
38 |
39 | CSPRNG_sample
40 | .\$(Platform)\$(Config)
41 | .\$(Platform)\$(Config)
42 | System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace)
43 |
44 |
45 | Debug
46 | true
47 | Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)
48 | vclwinx;DataSnapServer;P4DMatplotLib;P4DPandas;fmx;emshosting;vclie;DbxCommonDriver;bindengine;IndyIPCommon;VCLRESTComponents;DBXMSSQLDriver;FireDACCommonODBC;emsclient;FireDACCommonDriver;appanalytics;IndyProtocols;vclx;Skia.Package.RTL;IndyIPClient;dbxcds;vcledge;bindcompvclwinx;FmxTeeUI;P4DONNXRuntime;emsedge;bindcompfmx;DBXFirebirdDriver;inetdb;FireDACSqliteDriver;DbxClientDriver;FireDACASADriver;Tee;soapmidas;vclactnband;TeeUI;fmxFireDAC;dbexpress;Python;FireDACInfxDriver;P4DTools;DBXMySQLDriver;P4DPyPackage;VclSmp;inet;DataSnapCommon;PythonVcl;vcltouch;fmxase;P4DOpenCV;DBXOdbcDriver;dbrtl;FireDACDBXDriver;Skia.Package.FMX;FireDACOracleDriver;fmxdae;TeeDB;FireDACMSAccDriver;CustomIPTransport;FireDACMSSQLDriver;P4DSciPy;DataSnapIndy10ServerTransport;P4DTensorFlow;DataSnapConnectors;P4DKeras;vcldsnap;DBXInterBaseDriver;FireDACMongoDBDriver;IndySystem;FireDACTDataDriver;Skia.Package.VCL;vcldb;vclFireDAC;bindcomp;FireDACCommon;DataSnapServerMidas;FireDACODBCDriver;emsserverresource;IndyCore;RESTBackendComponents;P4DScikitLearn;P4DPyTorch;bindcompdbx;rtl;FireDACMySQLDriver;FireDACADSDriver;RESTComponents;DBXSqliteDriver;vcl;IndyIPServer;dsnapxml;dsnapcon;DataSnapClient;DataSnapProviderClient;adortl;P4DNLTK;DBXSybaseASEDriver;FixInsight_12;DBXDb2Driver;vclimg;DataSnapFireDAC;emsclientfiredac;FireDACPgDriver;FireDAC;FireDACDSDriver;inetdbxpress;xmlrtl;tethering;P4DEnvironment;bindcompvcl;dsnap;CloudService;DBXSybaseASADriver;DBXOracleDriver;FireDACDb2Driver;DBXInformixDriver;P4DNumPy;fmxobj;bindcompvclsmp;FMXTee;DataSnapNativeClient;PythonFmx;AIAPI;DatasnapConnectorsFreePascal;soaprtl;soapserver;FireDACIBDriver;$(DCC_UsePackage)
49 | $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png
50 | $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png
51 | CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=
52 | 1033
53 |
54 |
55 | true
56 | true
57 | DEBUG;$(DCC_Define)
58 | true
59 | true
60 | false
61 | true
62 | true
63 |
64 |
65 | false
66 |
67 |
68 | 0
69 | RELEASE;$(DCC_Define)
70 | false
71 | 0
72 |
73 |
74 |
75 | MainSource
76 |
77 |
78 |
79 |
80 |
81 | Base
82 |
83 |
84 | Cfg_1
85 | Base
86 |
87 |
88 | Cfg_2
89 | Base
90 |
91 |
92 |
93 | Delphi.Personality.12
94 | Application
95 |
96 |
97 |
98 | CSPRNG_sample.dpr
99 |
100 |
101 |
102 | False
103 | False
104 | False
105 | False
106 | False
107 | True
108 | False
109 | False
110 | False
111 |
112 |
113 | 12
114 |
115 |
116 |
117 |
118 |
119 |
--------------------------------------------------------------------------------
/sample/CSPRNG_sample.res:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimmckeeth/DelphiCSPRNG/f49d935b20d06f61fc18461c71b22da56da48dca/sample/CSPRNG_sample.res
--------------------------------------------------------------------------------
/src/CSPRNG.Interfaces.pas:
--------------------------------------------------------------------------------
1 | unit CSPRNG.Interfaces;
2 |
3 | interface
4 |
5 | uses SysUtils;
6 |
7 | type
8 | ICSPRNGProvider = interface
9 | ///
10 | /// Generates a specified number of cryptographically secure random bytes.
11 | ///
12 | function GetBytes(const Count: Integer): TBytes;
13 |
14 | ///
15 | /// Generates a cryptographically secure random unsigned 32-bit integer.
16 | ///
17 | function GetUInt32(const max: UInt32 = High(UInt32)): UInt32;
18 |
19 | ///
20 | /// Generates a cryptographically secure random signed 32-bit integer.
21 | ///
22 | function GetInt32(const max: Int32 = High(Int32)): Int32;
23 |
24 | ///
25 | /// Generates a cryptographically secure random signed 64-bit integer.
26 | ///
27 | function GetInt64(const max: Int64 = High(Int64)): Int64;
28 |
29 | ///
30 | /// Generates a cryptographically secure random unsigned 64-bit integer.
31 | ///
32 | function GetUInt64(const max: UInt64 = High(UInt64)): UInt64;
33 |
34 | ///
35 | /// Generates a cryptographically secure random float between 0 and 1
36 | ///
37 | function GetFloat: Double;
38 |
39 | ///
40 | /// Generates a BASE64 encoded random string
41 | ///
42 | function GetBase64(const len: Integer = 1024): String;
43 | end;
44 |
45 |
46 | implementation
47 |
48 | end.
49 |
--------------------------------------------------------------------------------
/src/CSPRNG.Provider.Base.pas:
--------------------------------------------------------------------------------
1 | unit CSPRNG.Provider.Base;
2 |
3 | interface
4 |
5 | uses
6 | System.SysUtils, CSPRNG.Interfaces,
7 | System.NetEncoding;
8 |
9 | type
10 | ///
11 | /// Abstract base class for CSPRNG providers.
12 | ///
13 | TCSPRNGProviderBase = class abstract(TInterfacedObject, ICSPRNGProvider)
14 |
15 | protected
16 | function GetBytes(const Count: Integer): TBytes; virtual; abstract;
17 | public
18 |
19 | function GetFloat: Double;
20 | function GetUInt32(const max: UInt32 = High(UInt32)): UInt32;
21 | function GetInt32(const max: Int32 = High(Int32)): Int32;
22 | function GetInt64(const max: Int64 = High(Int64)): Int64;
23 | function GetUInt64(const max: UInt64 = High(UInt64)): UInt64;
24 | function GetBase64(const len: Integer = 1024): String;
25 |
26 | // Helpers
27 | class function ToUInt32(const Bytes: TBytes): UInt32;
28 | class function ToInt32(const Bytes: TBytes): Int32;
29 | class function ToInt64(const Bytes: TBytes): Int64;
30 | class function ToUInt64(const Bytes: TBytes): UInt64;
31 | class function PadBytes(const Bytes: TBytes; PadLength: Integer): TBytes; static;
32 |
33 | end;
34 |
35 | implementation
36 |
37 | { TCSPRNGProviderBase }
38 |
39 | function TCSPRNGProviderBase.GetUInt32(const max: UInt32 = High(UInt32)): UInt32;
40 | var
41 | RandomBytes: TBytes;
42 | Value: UInt64;
43 | begin
44 | if max = 0 then
45 | Exit(0); // Handle the case where max is 0
46 |
47 | RandomBytes := GetBytes(SizeOf(UInt32)); // Get 4 random bytes
48 | Value := ToUInt64(RandomBytes);
49 |
50 | Result := UInt32(Value mod (UInt64(max) + 1)); // Modulo and cast to UInt32
51 | end;
52 |
53 | function TCSPRNGProviderBase.GetInt32(const max: Int32 = High(Int32)): Int32;
54 | var
55 | RandomBytes: TBytes;
56 | Value: UInt64;
57 | begin
58 | if max < 0 then
59 | raise Exception.Create('Max value must be greater than or equal to 0');
60 |
61 | RandomBytes := GetBytes(SizeOf(Int32)); // Get 4 random bytes
62 | Value := ToUInt64(RandomBytes); // Convert to UInt64
63 |
64 | // Calculate the range size and adjust the modulo operation for signed values
65 | var rangeSize := UInt64(max) + 1; // Range from 0 to max (inclusive)
66 | var adjustedValue := Value mod rangeSize;
67 |
68 | // If the adjusted value is too large to fit in Int32 after conversion, subtract the range size
69 | if adjustedValue > High(Int32) then
70 | adjustedValue := adjustedValue - rangeSize;
71 |
72 | Result := Int32(adjustedValue); // Safely cast to Int32
73 | end;
74 |
75 | function TCSPRNGProviderBase.GetInt64(const max: Int64 = High(Int64)): Int64;
76 | var
77 | RandomBytes: TBytes;
78 | Value: UInt64;
79 | begin
80 | if max < 0 then
81 | raise Exception.Create('Max value must be greater than or equal to 0');
82 |
83 | RandomBytes := GetBytes(SizeOf(Int64));
84 | Value := ToUInt64(RandomBytes);
85 |
86 | var rangeSize := UInt64(max) + 1;
87 | var adjustedValue := Value mod rangeSize;
88 |
89 | if adjustedValue > High(Int64) then
90 | adjustedValue := adjustedValue - rangeSize;
91 |
92 | Result := Int64(adjustedValue);
93 | end;
94 |
95 | function TCSPRNGProviderBase.GetUInt64(const max: UInt64 = High(UInt64)): UInt64;
96 | var
97 | RandomBytes: TBytes;
98 | Value: UInt64;
99 | begin
100 | if max = 0 then
101 | Exit(0); // Handle the case where max is 0
102 |
103 | // Special handling when max is High(UInt64) to avoid overflow
104 | if max = High(UInt64) then
105 | begin
106 | RandomBytes := GetBytes(SizeOf(UInt64)); // Get 8 random bytes
107 | Exit(ToUInt64(RandomBytes));
108 | end;
109 |
110 | RandomBytes := GetBytes(SizeOf(UInt64)); // Get 8 random bytes
111 | Value := ToUInt64(RandomBytes);
112 |
113 | // Optimized range reduction without a loop
114 | var divisor := High(UInt64) div (max + 1);
115 | Result := Value div divisor; // Integer division ensures the result is in the range
116 | end;
117 |
118 |
119 | class function TCSPRNGProviderBase.PadBytes(const Bytes: TBytes; PadLength: Integer): TBytes;
120 | begin
121 | if Length(Bytes) < PadLength then
122 | begin
123 | SetLength(Result, PadLength);
124 | FillChar(Result[0], PadLength, 0); // Fill with zeros
125 | if Length(Bytes) > 0 then // Only move bytes if the input array is not empty
126 | Move(Bytes[0], Result[PadLength - Length(Bytes)], Length(Bytes));
127 | end
128 | else
129 | Result := Copy(Bytes, 0, PadLength); // Copy only the required bytes
130 | end;
131 |
132 | class function TCSPRNGProviderBase.ToUInt32(const Bytes: TBytes): UInt32;
133 | begin
134 | var localBytes := PadBytes(Bytes, SizeOf(UInt32));
135 |
136 | // Combine bytes using bit shifting to avoid potential endianness issues
137 | Result := UInt32(localBytes[0]) +
138 | (UInt32(localBytes[1]) shl 8) +
139 | (UInt32(localBytes[2]) shl 16) +
140 | (UInt32(localBytes[3]) shl 24);
141 | end;
142 |
143 | class function TCSPRNGProviderBase.ToInt32(const Bytes: TBytes): Int32;
144 | var
145 | localBytes: TBytes;
146 | begin
147 | localBytes := PadBytes(Bytes, SizeOf(Int32));
148 |
149 | // Combine bytes using bit shifting to avoid potential endianness issues
150 | Result := Int32(localBytes[0]) +
151 | (Int32(localBytes[1]) shl 8) +
152 | (Int32(localBytes[2]) shl 16) +
153 | (Int32(localBytes[3]) shl 24);
154 | end;
155 |
156 | class function TCSPRNGProviderBase.ToInt64(const Bytes: TBytes): Int64;
157 | var
158 | localBytes: TBytes;
159 | begin
160 | localBytes := PadBytes(Bytes, SizeOf(Int64));
161 |
162 | // Combine bytes using bit shifting
163 | Result := Int64(localBytes[0]) +
164 | (Int64(localBytes[1]) shl 8) +
165 | (Int64(localBytes[2]) shl 16) +
166 | (Int64(localBytes[3]) shl 24) +
167 | (Int64(localBytes[4]) shl 32) +
168 | (Int64(localBytes[5]) shl 40) +
169 | (Int64(localBytes[6]) shl 48) +
170 | (Int64(localBytes[7]) shl 56);
171 | end;
172 |
173 | class function TCSPRNGProviderBase.ToUInt64(const Bytes: TBytes): UInt64;
174 | var
175 | localBytes: TBytes;
176 | begin
177 | localBytes := PadBytes(Bytes, SizeOf(UInt64));
178 |
179 | // Combine bytes using bit shifting
180 | Result := UInt64(localBytes[0]) +
181 | (UInt64(localBytes[1]) shl 8) +
182 | (UInt64(localBytes[2]) shl 16) +
183 | (UInt64(localBytes[3]) shl 24) +
184 | (UInt64(localBytes[4]) shl 32) +
185 | (UInt64(localBytes[5]) shl 40) +
186 | (UInt64(localBytes[6]) shl 48) +
187 | (UInt64(localBytes[7]) shl 56);
188 | end;
189 |
190 | function TCSPRNGProviderBase.GetFloat: Double;
191 | var
192 | Bytes: TBytes;
193 | RandomInt: UInt64;
194 | begin
195 | Bytes := GetBytes(SizeOf(UInt64));
196 | RandomInt := PUInt64(@Bytes[0])^; // Assuming little-endian
197 | Result := RandomInt / UInt64(High(UInt64)); // Scale to [0, 1)
198 | end;
199 |
200 | function TCSPRNGProviderBase.GetBase64(const len: Integer = 1024): String;
201 | var
202 | Bytes: TBytes;
203 | begin
204 | Bytes := GetBytes(len);
205 | var Encoding := TBase64Encoding.Create(0);
206 | try
207 | Result := Encoding.EncodeBytesToString(Bytes); // Convert to Base64
208 | finally
209 | Encoding.Free;
210 | end;
211 | end;
212 |
213 | end.
214 |
--------------------------------------------------------------------------------
/src/CSPRNG.Provider.MacOS64.pas:
--------------------------------------------------------------------------------
1 | unit CSPRNG.Provider.MacOS64;
2 |
3 | interface
4 |
5 | {$IFDEF OSX}
6 |
7 | uses
8 | CSPRNG.Provider.Base, SysUtils, Classes, Posix.Base, Posix.Unistd, Posix.Fcntl, Posix.Errno;
9 |
10 | type
11 | ///
12 | /// macOS (64-bit) implementation of the CSPRNG provider using platform entropy sources.
13 | ///
14 | TCSPRNGProviderMacOS64 = class(TCSPRNGProviderBase)
15 | protected
16 | ///
17 | /// Seeds the CSPRNG using the provided byte array.
18 | ///
19 | procedure SeedFromBytes(const SeedData: TBytes); override;
20 |
21 | ///
22 | /// Seeds the CSPRNG using the platform's entropy source (/dev/urandom).
23 | ///
24 | procedure SeedFromEntropySource; override;
25 |
26 | ///
27 | /// Generates a specified number of cryptographically secure random bytes using /dev/urandom.
28 | ///
29 | function GetBytes(const Count: Integer): TBytes; override;
30 | end;
31 |
32 | implementation
33 |
34 | { TCSPRNGProviderMacOS64 }
35 |
36 | procedure TCSPRNGProviderMacOS64.SeedFromBytes(const SeedData: TBytes);
37 | begin
38 | // Like on Linux, custom seeding is generally not necessary or supported.
39 | raise Exception.Create('Custom seeding is not supported for the macOS provider');
40 | end;
41 |
42 | procedure TCSPRNGProviderMacOS64.SeedFromEntropySource;
43 | begin
44 | // On macOS, no extra action is needed since /dev/urandom provides entropy.
45 | end;
46 |
47 | function TCSPRNGProviderMacOS64.GetBytes(const Count: Integer): TBytes;
48 | var
49 | FileStream: TFileStream;
50 | BytesRead: Integer;
51 | begin
52 | SetLength(Result, Count);
53 |
54 | // Open /dev/urandom as a file stream on macOS to get random bytes
55 | FileStream := TFileStream.Create('/dev/urandom', fmOpenRead);
56 | try
57 | BytesRead := FileStream.Read(Result[0], Count);
58 | if BytesRead <> Count then
59 | raise Exception.Create('Unable to read sufficient random bytes from /dev/urandom on macOS');
60 | finally
61 | FileStream.Free;
62 | end;
63 | end;
64 |
65 | {$ELSE}
66 | implementation
67 | {$ENDIF}
68 |
69 | end.
70 |
71 |
--------------------------------------------------------------------------------
/src/CSPRNG.Provider.Posix.pas:
--------------------------------------------------------------------------------
1 | unit CSPRNG.Provider.Posix;
2 |
3 | interface
4 |
5 | {$IFDEF POSIX}
6 |
7 | uses
8 | CSPRNG.Provider.Base, SysUtils, Classes, Posix.Base, Posix.Unistd, Posix.Fcntl, Posix.Errno;
9 |
10 | type
11 | ///
12 | /// Linux (64-bit) implementation of the CSPRNG provider using platform entropy sources.
13 | ///
14 | TCSPRNGProviderPosix = class(TCSPRNGProviderBase)
15 | protected
16 | ///
17 | /// Generates a specified number of cryptographically secure random bytes using /dev/urandom.
18 | ///
19 | function GetBytes(const Count: Integer): TBytes; override;
20 | end;
21 |
22 | implementation
23 |
24 | { TCSPRNGProviderLinux64 }
25 |
26 | function TCSPRNGProviderPosix.GetBytes(const Count: Integer): TBytes;
27 | var
28 | FileStream: TFileStream;
29 | BytesRead: Integer;
30 | begin
31 | SetLength(Result, Count);
32 |
33 | // Open /dev/urandom as a file stream
34 | FileStream := TFileStream.Create('/dev/urandom', fmOpenRead);
35 | try
36 | BytesRead := FileStream.Read(Result[0], Count);
37 | if BytesRead <> Count then
38 | raise Exception.Create('Unable to read sufficient random bytes from /dev/urandom');
39 | finally
40 | FileStream.Free;
41 | end;
42 | end;
43 |
44 | {$ELSE}
45 | implementation
46 | {$ENDIF}
47 |
48 | end.
49 |
50 |
51 |
--------------------------------------------------------------------------------
/src/CSPRNG.Provider.Windows.pas:
--------------------------------------------------------------------------------
1 | unit CSPRNG.Provider.Windows;
2 |
3 | interface
4 |
5 | {$IFDEF MSWINDOWS}
6 |
7 | uses
8 | System.SysUtils,
9 | Winapi.Windows,
10 | CSPRNG.Interfaces,
11 | CSPRNG.Provider.Base;
12 |
13 | type
14 | BCRYPT_ALG_HANDLE = PVOID;
15 | TWindowsCSPRNGProvider = class(TCSPRNGProviderBase, ICSPRNGProvider)
16 | private
17 | FHandle: BCRYPT_ALG_HANDLE;
18 | procedure SeedFromEntropySource; // Add a field to store the seed
19 |
20 | public
21 | constructor Create;
22 | destructor Destroy; override;
23 |
24 | // ICSPRNGProvider implementation
25 | function GetBytes(const Count: Integer): TBytes; override;
26 | end;
27 |
28 | implementation
29 |
30 | uses
31 | System.Math;
32 |
33 | const
34 | BCRYPT_RNG_ALGORITHM = 'RNG';
35 | BCRYPT_RNG_USE_ENTROPY_IN_BUFFER = $00000001;
36 |
37 | type
38 | PBCRYPT_ALG_HANDLE = ^BCRYPT_ALG_HANDLE;
39 |
40 | function BCryptOpenAlgorithmProvider(phAlgorithm: PBCRYPT_ALG_HANDLE;
41 | pszAlgId: LPCWSTR; pszImplementation: LPCWSTR; dwFlags: ULONG): NTSTATUS; stdcall; external 'bcrypt.dll';
42 |
43 | function BCryptCloseAlgorithmProvider(hAlgorithm: BCRYPT_ALG_HANDLE;
44 | dwFlags: ULONG): NTSTATUS; stdcall; external 'bcrypt.dll';
45 |
46 | function BCryptGenRandom(hAlgorithm: BCRYPT_ALG_HANDLE; pbBuffer: PBYTE;
47 | cbBuffer: ULONG; dwFlags: ULONG): NTSTATUS; stdcall; external 'bcrypt.dll';
48 |
49 | const
50 | STATUS_SUCCESS = 0; // NTSTATUS Success value
51 |
52 |
53 | { TWindowsCSPRNGProvider }
54 |
55 | constructor TWindowsCSPRNGProvider.Create;
56 | begin
57 | inherited Create;
58 | if BCryptOpenAlgorithmProvider(@FHandle, BCRYPT_RNG_ALGORITHM, nil, 0) <> STATUS_SUCCESS then
59 | raise Exception.Create('Failed to open BCrypt RNG provider');
60 |
61 | SeedFromEntropySource();
62 | end;
63 |
64 | destructor TWindowsCSPRNGProvider.Destroy;
65 | begin
66 | BCryptCloseAlgorithmProvider(FHandle, 0);
67 | inherited;
68 | end;
69 |
70 | procedure TWindowsCSPRNGProvider.SeedFromEntropySource;
71 | begin
72 | // Use the default system-provided entropy
73 | BCryptGenRandom(FHandle, nil, 0, 0);
74 | end;
75 |
76 | function TWindowsCSPRNGProvider.GetBytes(const Count: Integer): TBytes;
77 | var
78 | pBytes: PByte;
79 | begin
80 | SetLength(Result, Count);
81 | pBytes := PByte(Result);
82 | if BCryptGenRandom(FHandle, pBytes, Count, 0) <> STATUS_SUCCESS then
83 | raise Exception.Create('Failed to generate random bytes');
84 | end;
85 | {$ELSE}
86 | implementation
87 | {$ENDIF}
88 |
89 | end.
90 |
91 |
--------------------------------------------------------------------------------
/src/CSPRNG.Provider.iOS.pas:
--------------------------------------------------------------------------------
1 | unit CSPRNG.Provider.iOS;
2 |
3 | interface
4 |
5 | {$ifdef IOS}
6 | uses
7 | CSPRNG.Provider.Base, Macapi.CoreFoundation, Macapi.Security, SysUtils;
8 |
9 | type
10 | ///
11 | /// iOS implementation of the CSPRNG provider using SecRandomCopyBytes.
12 | ///
13 | TCSPRNGProvideriOS = class(TCSPRNGProviderBase)
14 | protected
15 | procedure SeedFromBytes(const SeedData: TBytes); override;
16 | procedure SeedFromEntropySource; override;
17 | function GetBytes(const Count: Integer): TBytes; override;
18 | end;
19 |
20 | implementation
21 |
22 | { TCSPRNGProvideriOS }
23 |
24 | procedure TCSPRNGProvideriOS.SeedFromBytes(const SeedData: TBytes);
25 | begin
26 | // Seeding is not necessary on iOS.
27 | raise Exception.Create('Custom seeding is not supported on iOS.');
28 | end;
29 |
30 | procedure TCSPRNGProvideriOS.SeedFromEntropySource;
31 | begin
32 | // Seeding is not necessary for iOS.
33 | end;
34 |
35 | function TCSPRNGProvideriOS.GetBytes(const Count: Integer): TBytes;
36 | var
37 | Status: Integer;
38 | begin
39 | SetLength(Result, Count);
40 | Status := SecRandomCopyBytes(kSecRandomDefault, Count, @Result[0]);
41 |
42 | if Status <> errSecSuccess then
43 | raise Exception.Create('Unable to generate random bytes using SecRandomCopyBytes');
44 | end;
45 |
46 | {$ELSE}
47 | implementation
48 | {$endif}
49 |
50 | end.
51 |
52 |
--------------------------------------------------------------------------------
/src/CSPRNG.pas:
--------------------------------------------------------------------------------
1 | unit CSPRNG;
2 |
3 | interface
4 |
5 | uses
6 | System.SysUtils, CSPRNG.Interfaces;
7 |
8 | function GetCSPRNGProvider: ICSPRNGProvider;
9 |
10 | implementation
11 |
12 | {$IF Defined(MSWINDOWS)}
13 | uses CSPRNG.Provider.Windows;
14 | function GetCSPRNGProvider: ICSPRNGProvider;
15 | begin
16 | Result := TWindowsCSPRNGProvider.Create; // Create Windows provider
17 | end;
18 | {$ENDIF}
19 |
20 | {$IFDEF POSIX}
21 | uses CSPRNG.Provider.Posix;
22 |
23 | function GetCSPRNGProvider: ICSPRNGProvider;
24 | begin
25 | Result := TCSPRNGProviderPosix.Create;
26 | end;
27 | {$ENDIF}
28 |
29 | {$IFDEF MACOS}
30 | uses CSPRNG.Provider.MacOS64;
31 |
32 | function GetCSPRNGProvider: ICSPRNGProvider;
33 | begin
34 | Result := TCSPRNGProviderMacOS64.Create;
35 | end;
36 | {$ENDIF}
37 |
38 | initialization
39 |
40 | finalization
41 |
42 | end.
43 |
44 |
--------------------------------------------------------------------------------
/src/CSPRNG_sample.dpr:
--------------------------------------------------------------------------------
1 | program CSPRNG_sample;
2 |
3 | {$APPTYPE CONSOLE}
4 |
5 | {$R *.res}
6 |
7 | uses
8 | System.SysUtils,
9 | CSPRNG in 'CSPRNG.pas',
10 | CSPRNG.Provider.Windows in 'CSPRNG.Provider.Windows.pas',
11 | CSPRNG.Interfaces in 'CSPRNG.Interfaces.pas',
12 | CSPRNG.Provider.Base in 'CSPRNG.Provider.Base.pas',
13 | CSPRNG.Provider.Posix in 'CSPRNG.Provider.Posix.pas',
14 | CSPRNG.Provider.iOS in 'CSPRNG.Provider.iOS.pas',
15 | CSPRNG.Provider.MacOS64 in 'CSPRNG.Provider.MacOS64.pas';
16 |
17 | begin
18 | try
19 | var rnd := GetCSPRNGProvider;
20 | for var b in rnd.GetBytes(1000) do
21 | begin
22 | write(IntToHex(b, 2).ToLower);
23 | end;
24 | Writeln;
25 | const limit = 5;
26 | writeln(' - Float -');
27 | for var i := 0 to limit do Writeln(rnd.GetFloat);
28 | writeln(' - UInt32(max) -');
29 | for var i := 0 to limit do Writeln(rnd.GetUInt32);
30 | writeln(' - UInt32(quarter) -');
31 | for var i := 0 to limit do Writeln(rnd.GetUInt32(High(UInt32) div 4));
32 | writeln(' - UInt32(small) -');
33 | for var i := 0 to limit do Writeln(rnd.GetUInt32($F0));
34 |
35 |
36 | writeln(' - Int32(max) -');
37 | for var i := 0 to limit do Writeln(rnd.GetInt32());
38 | writeln(' - Int32(quarter) -');
39 | for var i := 0 to limit do Writeln(rnd.GetInt32(High(Int32) div 2));
40 | writeln(' - Int32(small) -');
41 | for var i := 0 to limit do Writeln(rnd.GetInt32($F0));
42 |
43 | writeln(' - UInt64(max) -');
44 | for var i := 0 to limit do Writeln(rnd.GetUInt64);
45 | writeln(' - UInt64(quarter) -');
46 | for var i := 0 to limit do Writeln(rnd.GetUInt64(High(UInt64) div 4));
47 | writeln(' - UInt64(small) -');
48 | for var i := 0 to limit do Writeln(rnd.GetUInt64($F0));
49 |
50 | writeln(' - Int64(max) -');
51 | for var i := 0 to limit do Writeln(rnd.GetInt64);
52 | writeln(' - Int64(quarter) -');
53 | for var i := 0 to limit do Writeln(rnd.GetInt64(High(UInt64) div 4));
54 | writeln(' - Int64(small) -');
55 | for var i := 0 to limit do Writeln(rnd.GetInt64($F0));
56 | except
57 | on E: Exception do
58 | Writeln(E.ClassName, ': ', E.Message);
59 | end;
60 | Writeln;
61 | Writeln('Done!');
62 | Readln;
63 | end.
64 |
--------------------------------------------------------------------------------
/src/CSPRNG_sample.dproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | True
4 | Console
5 | Debug
6 | None
7 | CSPRNG_sample.dpr
8 | Win32
9 | {7F7C03D2-1B62-4C4B-8FA9-C2EEB044296C}
10 | CSPRNG_sample
11 | 20.2
12 | 33923
13 |
14 |
15 | true
16 |
17 |
18 | true
19 | Base
20 | true
21 |
22 |
23 | true
24 | Base
25 | true
26 |
27 |
28 | true
29 | Base
30 | true
31 |
32 |
33 | true
34 | Base
35 | true
36 |
37 |
38 | true
39 | Base
40 | true
41 |
42 |
43 | true
44 | Cfg_1
45 | true
46 | true
47 |
48 |
49 | true
50 | Base
51 | true
52 |
53 |
54 | CSPRNG_sample
55 | .\$(Platform)\$(Config)
56 | .\$(Platform)\$(Config)
57 | System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace)
58 |
59 |
60 | Debug
61 | package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey=;minSdkVersion=23;targetSdkVersion=34
62 |
63 |
64 | Debug
65 | true
66 | Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)
67 | vclwinx;DataSnapServer;P4DMatplotLib;P4DPandas;fmx;emshosting;vclie;DbxCommonDriver;bindengine;IndyIPCommon;VCLRESTComponents;DBXMSSQLDriver;FireDACCommonODBC;emsclient;FireDACCommonDriver;appanalytics;IndyProtocols;vclx;Skia.Package.RTL;IndyIPClient;dbxcds;vcledge;bindcompvclwinx;FmxTeeUI;P4DONNXRuntime;emsedge;bindcompfmx;DBXFirebirdDriver;inetdb;FireDACSqliteDriver;DbxClientDriver;FireDACASADriver;Tee;soapmidas;vclactnband;TeeUI;fmxFireDAC;dbexpress;Python;FireDACInfxDriver;P4DTools;DBXMySQLDriver;P4DPyPackage;VclSmp;inet;DataSnapCommon;PythonVcl;vcltouch;fmxase;P4DOpenCV;DBXOdbcDriver;dbrtl;FireDACDBXDriver;Skia.Package.FMX;FireDACOracleDriver;fmxdae;TeeDB;FireDACMSAccDriver;CustomIPTransport;FireDACMSSQLDriver;P4DSciPy;DataSnapIndy10ServerTransport;P4DTensorFlow;DataSnapConnectors;P4DKeras;vcldsnap;DBXInterBaseDriver;FireDACMongoDBDriver;IndySystem;FireDACTDataDriver;Skia.Package.VCL;vcldb;vclFireDAC;bindcomp;FireDACCommon;DataSnapServerMidas;FireDACODBCDriver;emsserverresource;IndyCore;RESTBackendComponents;P4DScikitLearn;P4DPyTorch;bindcompdbx;rtl;FireDACMySQLDriver;FireDACADSDriver;RESTComponents;DBXSqliteDriver;vcl;IndyIPServer;dsnapxml;dsnapcon;DataSnapClient;DataSnapProviderClient;adortl;P4DNLTK;DBXSybaseASEDriver;FixInsight_12;DBXDb2Driver;vclimg;DataSnapFireDAC;emsclientfiredac;FireDACPgDriver;FireDAC;FireDACDSDriver;inetdbxpress;xmlrtl;tethering;P4DEnvironment;bindcompvcl;dsnap;CloudService;DBXSybaseASADriver;DBXOracleDriver;FireDACDb2Driver;DBXInformixDriver;P4DNumPy;fmxobj;bindcompvclsmp;FMXTee;DataSnapNativeClient;PythonFmx;AIAPI;DatasnapConnectorsFreePascal;soaprtl;soapserver;FireDACIBDriver;$(DCC_UsePackage)
68 | $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png
69 | $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png
70 | CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=
71 | 1033
72 |
73 |
74 | Debug
75 | Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace)
76 | CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=
77 | 1033
78 |
79 |
80 | Debug
81 | $(MSBuildProjectName)
82 | true
83 | CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0;CFBundleShortVersionString=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;NSLocationAlwaysAndWhenInUseUsageDescription=The reason for accessing the location information of the user;UIBackgroundModes=;NSContactsUsageDescription=The reason for accessing the contacts;NSPhotoLibraryUsageDescription=The reason for accessing the photo library;NSPhotoLibraryAddUsageDescription=The reason for adding to the photo library;NSCameraUsageDescription=The reason for accessing the camera;NSFaceIDUsageDescription=The reason for accessing the face id;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSSiriUsageDescription=The reason for accessing Siri;ITSAppUsesNonExemptEncryption=false;NSBluetoothAlwaysUsageDescription=The reason for accessing bluetooth;NSBluetoothPeripheralUsageDescription=The reason for accessing bluetooth peripherals;NSCalendarsUsageDescription=The reason for accessing the calendar data;NSRemindersUsageDescription=The reason for accessing the reminders;NSMotionUsageDescription=The reason for accessing the accelerometer;NSSpeechRecognitionUsageDescription=The reason for requesting to send user data to Apple's speech recognition servers
84 | iPhoneAndiPad
85 |
86 |
87 | true
88 | true
89 | DEBUG;$(DCC_Define)
90 | true
91 | true
92 | false
93 | true
94 | true
95 |
96 |
97 | false
98 |
99 |
100 | 0
101 | RELEASE;$(DCC_Define)
102 | false
103 | 0
104 |
105 |
106 |
107 | MainSource
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 | Base
118 |
119 |
120 | Cfg_1
121 | Base
122 |
123 |
124 | Cfg_2
125 | Base
126 |
127 |
128 |
129 | Delphi.Personality.12
130 | Application
131 |
132 |
133 |
134 | CSPRNG_sample.dpr
135 |
136 |
137 |
138 | False
139 | True
140 | True
141 | False
142 | False
143 | True
144 | True
145 | False
146 | True
147 | False
148 |
149 |
150 | 12
151 |
152 |
153 |
154 |
155 |
156 |
--------------------------------------------------------------------------------
/src/CSPRNG_sample.res:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimmckeeth/DelphiCSPRNG/f49d935b20d06f61fc18461c71b22da56da48dca/src/CSPRNG_sample.res
--------------------------------------------------------------------------------
/tests/CSPRNG.Tests.Providers.pas:
--------------------------------------------------------------------------------
1 | unit CSPRNG.Tests.Providers;
2 |
3 | interface
4 |
5 | uses
6 | SysUtils,
7 | DUnitX.TestFramework,
8 | CSPRNG,
9 | CSPRNG.Interfaces;
10 |
11 | type
12 |
13 | [TestFixture]
14 | TCSPRNGProviderTests = class
15 | private
16 | FCSPRNGProvider: ICSPRNGProvider;
17 | public
18 | [Setup]
19 | procedure Setup;
20 | [TearDown]
21 | procedure TearDown;
22 |
23 | [Test]
24 | procedure TestGetBytes_Length;
25 | [Test]
26 | procedure TestGetBytes_Randomness;
27 |
28 | [Test]
29 | procedure TestPadBytes_EmptyArrayTo4;
30 | [Test]
31 | procedure TestPadBytes_ExactLengthTo4;
32 | [Test]
33 | procedure TestPadBytes_LongArrayTo4;
34 | [Test]
35 | procedure TestPadBytes_ShortArrayTo4;
36 | [Test]
37 | procedure TestPadBytes_ShortArrayTo8;
38 | [Test]
39 | procedure TestPadBytes_ExactLengthTo8;
40 | [Test]
41 | procedure TestPadBytes_LongArrayTo8;
42 | [Test]
43 | procedure TestPadBytes_EmptyArrayTo8;
44 |
45 | [Test]
46 | [TestCase('UInt32_DefaultRange', '123456')]
47 | [TestCase('UInt32_SmallRange', '20')]
48 | procedure TestGetUInt32(const ExpectedMax: string);
49 |
50 | [Test]
51 | [TestCase('Int64_DefaultRange', '9223372036854775807')]
52 | [TestCase('Int64_SmallRange', '1000000')]
53 | [TestCase('Int64_SingleValue', '5')]
54 | procedure TestGetInt64(const ExpectedMax: string);
55 |
56 | [Test]
57 | [TestCase('Int32_DefaultRange', '2147483647')]
58 | [TestCase('Int32_SmallRange', '100')]
59 | [TestCase('Int32_SingleValue', '5')]
60 | procedure TestGetInt32(const ExpectedMax: string);
61 |
62 | [Test]
63 | [TestCase('UInt64_DefaultRange', '$FFFFFFFFFFFFFFFF')]
64 | [TestCase('UInt64_SmallRange', '1000000')]
65 | [TestCase('UInt64_SingleValue', '5')]
66 | procedure TestGetUInt64(const ExpectedMax: string);
67 |
68 | [Test]
69 | [TestCase('Len64','64')]
70 | [TestCase('Len512','512')]
71 | [TestCase('Len2048','2048')]
72 | procedure TestGetBase64_CustomLength(const Len: String);
73 | [Test]
74 | procedure TestGetBase64_Length;
75 | [Test]
76 | procedure TestGetBase64_Randomness;
77 | [Test]
78 | procedure TestGetBase64_ValidEncoding;
79 |
80 | [Test]
81 | procedure TestGetFloat_Range;
82 | [Test]
83 | procedure TestSeedFromBytes;
84 | [Test]
85 | procedure TestSeedFromEntropySource;
86 | end;
87 |
88 | implementation
89 |
90 | uses
91 | System.Math,
92 | System.NetEncoding,
93 | System.Generics.Collections,
94 | System.Classes,
95 | CSPRNG.Provider.Base;
96 |
97 | { TCSPRNGProviderTests }
98 |
99 | procedure TCSPRNGProviderTests.Setup;
100 | begin
101 | FCSPRNGProvider := GetCSPRNGProvider;
102 | end;
103 |
104 | procedure TCSPRNGProviderTests.TearDown;
105 | begin
106 | FCSPRNGProvider := nil;
107 | end;
108 |
109 | procedure TCSPRNGProviderTests.TestGetBytes_Length;
110 | const
111 | ByteCount = 1024;
112 | var
113 | Bytes: TBytes;
114 | begin
115 | Bytes := FCSPRNGProvider.GetBytes(ByteCount);
116 | Assert.AreEqual(UInt64(ByteCount), UInt64(Length(Bytes)),
117 | 'Incorrect number of bytes generated');
118 | end;
119 |
120 | procedure TCSPRNGProviderTests.TestGetBytes_Randomness;
121 | const
122 | ByteCount = 1024 * 1024; // 1MB of data
123 | begin
124 | var Bytes := FCSPRNGProvider.GetBytes(ByteCount);
125 |
126 | var Frequencies := TDictionary.Create;
127 | for var Byte in Bytes do
128 | begin
129 | var Frequency: Integer;
130 | if Frequencies.TryGetValue(Byte, Frequency) then
131 | Frequencies[Byte] := Frequency + 1
132 | else
133 | Frequencies.Add(Byte, 1);
134 | end;
135 |
136 | // Roughly check for uniform distribution (this is not a perfect statistical test)
137 | for var Frequency in Frequencies.Values do
138 | Assert.IsTrue(Frequency > ByteCount * 0.9 / 256, 'Insufficient randomness detected'); // 10% tolerance
139 | end;
140 |
141 |
142 | procedure TCSPRNGProviderTests.TestGetUInt32(const ExpectedMax: string);
143 | begin
144 | var MaxVal: Cardinal := StrToInt(ExpectedMax);
145 |
146 | for var i := 1 to 1000 do
147 | begin
148 | var Value := FCSPRNGProvider.GetUInt32(MaxVal);
149 | Assert.IsTrue(Value <= MaxVal, 'UInt32 above maximum');
150 | end;
151 | end;
152 |
153 | procedure TCSPRNGProviderTests.TestGetUInt64(const ExpectedMax: string);
154 | var
155 | MaxVal, Value: UInt64;
156 | i: Integer;
157 | begin
158 | MaxVal := StrToUInt64(ExpectedMax);
159 |
160 | for i := 1 to 1000 do
161 | begin
162 | Value := FCSPRNGProvider.GetUInt64(MaxVal);
163 | Assert.IsTrue(Value >= 0, 'UInt64 below minimum (0)');
164 | Assert.IsTrue(Value <= MaxVal, 'UInt64 above maximum');
165 | end;
166 | end;
167 |
168 | procedure TCSPRNGProviderTests.TestGetInt32(const ExpectedMax: string);
169 | var
170 | MaxVal, Value: Int32;
171 | i: Integer;
172 | begin
173 | MaxVal := StrToInt(ExpectedMax);
174 |
175 | for i := 1 to 1000 do
176 | begin
177 | Value := FCSPRNGProvider.GetInt32(MaxVal);
178 | Assert.IsTrue(Value >= 0, 'Int32 below minimum (0)');
179 | Assert.IsTrue(Value <= MaxVal, 'Int32 above maximum');
180 | end;
181 | end;
182 |
183 | procedure TCSPRNGProviderTests.TestGetInt64(const ExpectedMax: string);
184 | var
185 | MaxVal, Value: Int64;
186 | i: Integer;
187 | begin
188 | MaxVal := StrToInt64(ExpectedMax);
189 |
190 | for i := 1 to 1000 do
191 | begin
192 | Value := FCSPRNGProvider.GetInt64(MaxVal);
193 | Assert.IsTrue(Value >= 0, 'Int64 below minimum (0)');
194 | Assert.IsTrue(Value <= MaxVal, 'Int64 above maximum');
195 | end;
196 | end;
197 |
198 | procedure TCSPRNGProviderTests.TestGetFloat_Range;
199 | begin
200 | for var i := 1 to 1000 do
201 | begin
202 | var Value := FCSPRNGProvider.GetFloat;
203 | Assert.IsTrue(Value >= 0, 'Float below 0');
204 | Assert.IsTrue(Value < 1, 'Float not strictly less than 1');
205 | end;
206 | end;
207 |
208 | procedure TCSPRNGProviderTests.TestSeedFromBytes;
209 | begin
210 | // ... (Implement a test for SeedFromBytes.
211 | // This could involve checking for changes in the random output after seeding
212 | // or verifying that the same seed produces the same output sequence.)
213 | end;
214 |
215 | procedure TCSPRNGProviderTests.TestSeedFromEntropySource;
216 | begin
217 | // ... (Implement a test for SeedFromEntropySource.
218 | // This is more challenging, as it relies on system entropy.
219 | // You could potentially check if the output changes after reseeding, but it's not guaranteed.)
220 | end;
221 |
222 | procedure TCSPRNGProviderTests.TestPadBytes_ShortArrayTo4;
223 | begin
224 | var InputBytes: TBytes := [ $1, $2 ];
225 | var ExpectedBytes: TBytes := [ $0, $0, $1, $2 ];
226 | var ResultBytes := TCSPRNGProviderBase.PadBytes(InputBytes, SizeOf(UInt32));
227 | Assert.AreEqual(ExpectedBytes, ResultBytes);
228 | end;
229 |
230 | procedure TCSPRNGProviderTests.TestPadBytes_ExactLengthTo4;
231 | begin
232 | var InputBytes: TBytes := [ $1, $2, $3, $4 ];
233 | var ExpectedBytes: TBytes := [ $1, $2, $3, $4 ];
234 | var ResultBytes := TCSPRNGProviderBase.PadBytes(InputBytes, SizeOf(UInt32));
235 | Assert.AreEqual(ExpectedBytes, ResultBytes);
236 | end;
237 |
238 | procedure TCSPRNGProviderTests.TestPadBytes_LongArrayTo4;
239 | begin
240 | var InputBytes: TBytes := [ $1, $2, $3, $4, $5, $6 ];
241 | var ExpectedBytes: TBytes := [ $1, $2, $3, $4 ];
242 | var ResultBytes := TCSPRNGProviderBase.PadBytes(InputBytes, SizeOf(UInt32));
243 | Assert.AreEqual(ExpectedBytes, ResultBytes);
244 | end;
245 |
246 | procedure TCSPRNGProviderTests.TestPadBytes_EmptyArrayTo4;
247 | begin
248 | var InputBytes: TBytes := [];
249 | var ExpectedBytes: TBytes := [ $0, $0, $0, $0 ];
250 | var ResultBytes := TCSPRNGProviderBase.PadBytes(InputBytes, SizeOf(UInt32));
251 | Assert.AreEqual(ExpectedBytes, ResultBytes);
252 | end;
253 |
254 | procedure TCSPRNGProviderTests.TestPadBytes_ShortArrayTo8;
255 | begin
256 | var InputBytes: TBytes := [$1, $2, $3, $4];
257 | var ExpectedBytes: TBytes := [$0, $0, $0, $0, $1, $2, $3, $4];
258 | var ResultBytes := TCSPRNGProviderBase.PadBytes(InputBytes, SizeOf(UInt64));
259 | Assert.AreEqual(ExpectedBytes, ResultBytes, 'Incorrect padding: ShortArrayTo8');
260 | end;
261 |
262 | procedure TCSPRNGProviderTests.TestPadBytes_ExactLengthTo8;
263 | begin
264 | var InputBytes: TBytes := [$1, $2, $3, $4, $5, $6, $7, $8];
265 | var ExpectedBytes: TBytes := [$1, $2, $3, $4, $5, $6, $7, $8];
266 | var ResultBytes := TCSPRNGProviderBase.PadBytes(InputBytes, SizeOf(UInt64));
267 | Assert.AreEqual(ExpectedBytes, ResultBytes, 'Incorrect padding: ExactLengthTo8');
268 | end;
269 |
270 | procedure TCSPRNGProviderTests.TestPadBytes_LongArrayTo8;
271 | begin
272 | var InputBytes: TBytes := [$1, $2, $3, $4, $5, $6, $7, $8, $9, $A];
273 | var ExpectedBytes: TBytes := [$1, $2, $3, $4, $5, $6, $7, $8];
274 | var ResultBytes := TCSPRNGProviderBase.PadBytes(InputBytes, SizeOf(UInt64));
275 | Assert.AreEqual(ExpectedBytes, ResultBytes, 'Incorrect padding: LongArrayTo8');
276 | end;
277 |
278 | procedure TCSPRNGProviderTests.TestPadBytes_EmptyArrayTo8;
279 | begin
280 | var InputBytes: TBytes := [];
281 | var ExpectedBytes: TBytes := [$0, $0, $0, $0, $0, $0, $0, $0];
282 | var ResultBytes := TCSPRNGProviderBase.PadBytes(InputBytes, SizeOf(UInt64));
283 | Assert.AreEqual(ExpectedBytes, ResultBytes, 'Incorrect padding: EmptyArrayTo8');
284 | end;
285 |
286 | procedure TCSPRNGProviderTests.TestGetBase64_Length;
287 | begin
288 | var Bytes := TNetEncoding.Base64.DecodeStringToBytes(FCSPRNGProvider.GetBase64(1024));
289 | Assert.AreEqual(UInt64(1024), UInt64(Length(Bytes)), 'Incorrect Base64 string length');
290 | end;
291 |
292 | function GetBase64EncodedLength(ByteLength: Integer): Integer;
293 | begin
294 | Result := ((ByteLength + 2) div 3) * 4;
295 | end;
296 |
297 | procedure TCSPRNGProviderTests.TestGetBase64_CustomLength(const Len: String);
298 | var
299 | Base64String: string;
300 | iLen: Integer;
301 | ExpectedLength: Integer;
302 | begin
303 | iLen := StrToInt(Len);
304 | Base64String := FCSPRNGProvider.GetBase64(iLen);
305 |
306 | // Calculate expected length with padding
307 | ExpectedLength := GetBase64EncodedLength(iLen);
308 |
309 | Assert.AreEqual(ExpectedLength, Length(Base64String),
310 | 'Incorrect Base64 string length for custom length: ' + Len);
311 | end;
312 |
313 | procedure TCSPRNGProviderTests.TestGetBase64_Randomness;
314 | var
315 | Strings: TStringList;
316 | Base64String: string;
317 | i: Integer;
318 | begin
319 | Strings := TStringList.Create;
320 | try
321 | for i := 1 to 100 do
322 | begin
323 | Base64String := FCSPRNGProvider.GetBase64(64);
324 | Assert.IsFalse(Strings.Contains(Base64String), 'Duplicate Base64 string generated');
325 | Strings.Add(Base64String);
326 | end;
327 | finally
328 | Strings.Free;
329 | end;
330 | end;
331 |
332 | procedure TCSPRNGProviderTests.TestGetBase64_ValidEncoding;
333 | var
334 | Bytes: TBytes;
335 | begin
336 | var Base64String := FCSPRNGProvider.GetBase64;
337 | var Encoding := TBase64Encoding.Create(0);
338 | try
339 | Assert.WillNotRaiseAny(
340 | procedure
341 | begin
342 | Bytes := Encoding.DecodeStringToBytes(Base64String);
343 | end,
344 | 'Invalid Base64 encoding');
345 | Assert.AreEqual(Base64String, Encoding.EncodeBytesToString(Bytes),
346 | 'Failed round trip back to Base64.');
347 | finally
348 | Encoding.Free;
349 | end;
350 | end;
351 |
352 | initialization
353 | TDUnitX.Options.ExitBehavior := TDUnitXExitBehavior.Pause
354 | end.
355 |
356 |
--------------------------------------------------------------------------------
/tests/CSPRNG.Tests.dpr:
--------------------------------------------------------------------------------
1 | program CSPRNG.Tests;
2 |
3 | {$IFNDEF TESTINSIGHT}
4 | {$APPTYPE CONSOLE}
5 | {$ENDIF}
6 | {$STRONGLINKTYPES ON}
7 | uses
8 | System.SysUtils,
9 | {$IFDEF TESTINSIGHT}
10 | TestInsight.DUnitX,
11 | {$ELSE}
12 | DUnitX.Loggers.Console,
13 | DUnitX.Loggers.Xml.NUnit,
14 | {$ENDIF }
15 | DUnitX.TestFramework,
16 | CSPRNG.Tests.Providers in 'CSPRNG.Tests.Providers.pas',
17 | CSPRNG.Interfaces in '..\src\CSPRNG.Interfaces.pas',
18 | CSPRNG in '..\src\CSPRNG.pas',
19 | CSPRNG.Provider.Base in '..\src\CSPRNG.Provider.Base.pas',
20 | CSPRNG.Provider.Windows in '..\src\CSPRNG.Provider.Windows.pas',
21 | CSPRNG.Provider.Posix in '..\src\CSPRNG.Provider.Posix.pas',
22 | CSPRNG.Provider.MacOS64 in '..\src\CSPRNG.Provider.MacOS64.pas';
23 |
24 | { keep comment here to protect the following conditional from being removed by the IDE when adding a unit }
25 | {$IFNDEF TESTINSIGHT}
26 | var
27 | runner: ITestRunner;
28 | results: IRunResults;
29 | logger: ITestLogger;
30 | nunitLogger : ITestLogger;
31 | {$ENDIF}
32 | begin
33 | {$IFDEF TESTINSIGHT}
34 | TestInsight.DUnitX.RunRegisteredTests;
35 | {$ELSE}
36 | try
37 | //Check command line options, will exit if invalid
38 | TDUnitX.CheckCommandLine;
39 | //Create the test runner
40 | runner := TDUnitX.CreateRunner;
41 | //Tell the runner to use RTTI to find Fixtures
42 | runner.UseRTTI := True;
43 | //When true, Assertions must be made during tests;
44 | runner.FailsOnNoAsserts := False;
45 |
46 | //tell the runner how we will log things
47 | //Log to the console window if desired
48 | if TDUnitX.Options.ConsoleMode <> TDunitXConsoleMode.Off then
49 | begin
50 | logger := TDUnitXConsoleLogger.Create(TDUnitX.Options.ConsoleMode = TDunitXConsoleMode.Quiet);
51 | runner.AddLogger(logger);
52 | end;
53 | //Generate an NUnit compatible XML File
54 | nunitLogger := TDUnitXXMLNUnitFileLogger.Create(TDUnitX.Options.XMLOutputFile);
55 | runner.AddLogger(nunitLogger);
56 |
57 | //Run tests
58 | results := runner.Execute;
59 | if not results.AllPassed then
60 | System.ExitCode := EXIT_ERRORS;
61 |
62 | {$IFNDEF CI}
63 | //We don't want this happening when running under CI.
64 | if TDUnitX.Options.ExitBehavior = TDUnitXExitBehavior.Pause then
65 | begin
66 | System.Write('Done.. press key to quit.');
67 | System.Readln;
68 | end;
69 | {$ENDIF}
70 | except
71 | on E: Exception do
72 | System.Writeln(E.ClassName, ': ', E.Message);
73 | end;
74 | {$ENDIF}
75 | end.
76 |
--------------------------------------------------------------------------------
/tests/CSPRNG.Tests.dproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | True
4 | Console
5 | Debug
6 | None
7 | CSPRNG.Tests.dpr
8 | Win32
9 | {7D0CB541-0803-4C81-969D-19AF88443577}
10 | CSPRNG.Tests
11 | 20.2
12 | 4227
13 |
14 |
15 | true
16 |
17 |
18 | true
19 | Base
20 | true
21 |
22 |
23 | true
24 | Base
25 | true
26 |
27 |
28 | true
29 | Base
30 | true
31 |
32 |
33 | true
34 | Base
35 | true
36 |
37 |
38 | true
39 | Cfg_1
40 | true
41 | true
42 |
43 |
44 | true
45 | Base
46 | true
47 |
48 |
49 | CSPRNG_Tests
50 | .\$(Platform)\$(Config)
51 | .\$(Platform)\$(Config)
52 | System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace)
53 | $(DUnitX);$(DCC_UnitSearchPath)
54 | $(BDS)\bin\delphi_PROJECTICNS.icns
55 | $(BDS)\bin\delphi_PROJECTICON.ico
56 |
57 |
58 | Debug
59 | CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundleShortVersionString=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities;NSLocationUsageDescription=The reason for accessing the location information of the user;NSContactsUsageDescription=The reason for accessing the contacts;NSCalendarsUsageDescription=The reason for accessing the calendar data;NSRemindersUsageDescription=The reason for accessing the reminders;NSCameraUsageDescription=The reason for accessing the camera;NSMicrophoneUsageDescription=The reason for accessing the microphone;NSMotionUsageDescription=The reason for accessing the accelerometer;NSDesktopFolderUsageDescription=The reason for accessing the Desktop folder;NSDocumentsFolderUsageDescription=The reason for accessing the Documents folder;NSDownloadsFolderUsageDescription=The reason for accessing the Downloads folder;NSNetworkVolumesUsageDescription=The reason for accessing files on a network volume;NSRemovableVolumesUsageDescription=The reason for accessing files on a removable volume;NSSpeechRecognitionUsageDescription=The reason for requesting to send user data to Apple's speech recognition servers;ITSAppUsesNonExemptEncryption=false;NSBluetoothAlwaysUsageDescription=The reason for accessing the Bluetooth interface
60 |
61 |
62 | Debug
63 | Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)
64 | RaizeComponentsVcl;vclwinx;DataSnapServer;P4DPandas;fmx;vclie;DbxCommonDriver;bindengine;IndyIPCommon;VCLRESTComponents;DBXMSSQLDriver;FireDACCommonODBC;emsclient;ApperceptAPIClient;appanalytics;IndyProtocols;vclx;Skia.Package.RTL;dbxcds;vcledge;FmxTeeUI;P4DONNXRuntime;DBXFirebirdDriver;FireDACSqliteDriver;DbxClientDriver;soapmidas;TeeUI;dbexpress;Python;inet;PythonVcl;vcltouch;P4DOpenCV;FireDACDBXDriver;fmxdae;CustomIPTransport;FireDACMSSQLDriver;P4DSciPy;IndySystem;vclFireDAC;FireDACCommon;DataSnapServerMidas;FireDACODBCDriver;emsserverresource;P4DScikitLearn;P4DPyTorch;bindcompdbx;rtl;FireDACMySQLDriver;DBXSqliteDriver;DBXSybaseASEDriver;vclimg;DataSnapFireDAC;inetdbxpress;FireDAC;xmlrtl;P4DEnvironment;dsnap;FireDACDb2Driver;DBXOracleDriver;DBXInformixDriver;fmxobj;bindcompvclsmp;DataSnapNativeClient;AIAPI;DatasnapConnectorsFreePascal;P4DMatplotLib;emshosting;FireDACCommonDriver;RadiantShapesFmx_Design;IndyIPClient;bindcompvclwinx;emsedge;bindcompfmx;inetdb;FireDACASADriver;Tee;vclactnband;fmxFireDAC;FireDACInfxDriver;P4DTools;DBXMySQLDriver;P4DPyPackage;VclSmp;DataSnapCommon;fmxase;DBXOdbcDriver;dbrtl;FireDACOracleDriver;Skia.Package.FMX;TeeDB;FireDACMSAccDriver;DataSnapIndy10ServerTransport;P4DTensorFlow;DataSnapConnectors;P4DKeras;vcldsnap;DBXInterBaseDriver;FireDACMongoDBDriver;RadiantShapesFmx;FireDACTDataDriver;Skia.Package.VCL;vcldb;bindcomp;IndyCore;RESTBackendComponents;AWSSDKFMX;FireDACADSDriver;RaizeComponentsVclDb;AWSSDKVCL;RESTComponents;IndyIPServer;vcl;dsnapxml;adortl;dsnapcon;DataSnapClient;DataSnapProviderClient;P4DNLTK;FixInsight_12;DBXDb2Driver;emsclientfiredac;FireDACPgDriver;FireDACDSDriver;tethering;bindcompvcl;CloudService;DBXSybaseASADriver;P4DNumPy;FMXTee;PythonFmx;soaprtl;soapserver;FireDACIBDriver;$(DCC_UsePackage)
65 | CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=
66 | 1033
67 |
68 |
69 | Debug
70 | Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace)
71 | CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=
72 | 1033
73 |
74 |
75 | true
76 | true
77 | DEBUG;$(DCC_Define)
78 | true
79 | true
80 | false
81 | true
82 | true
83 |
84 |
85 | none
86 | false
87 | (None)
88 | 1033
89 |
90 |
91 | 0
92 | RELEASE;$(DCC_Define)
93 | false
94 | 0
95 |
96 |
97 |
98 | MainSource
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 | Base
109 |
110 |
111 | Cfg_1
112 | Base
113 |
114 |
115 | Cfg_2
116 | Base
117 |
118 |
119 |
120 | Delphi.Personality.12
121 | Console
122 |
123 |
124 |
125 | CSPRNG.Tests.dpr
126 |
127 |
128 |
129 |
130 | False
131 | False
132 | True
133 | True
134 | False
135 | True
136 | True
137 | False
138 | False
139 | False
140 |
141 |
142 | 12
143 |
144 |
145 |
146 |
147 |
148 |
--------------------------------------------------------------------------------
/tests/CSPRNG.Tests.res:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimmckeeth/DelphiCSPRNG/f49d935b20d06f61fc18461c71b22da56da48dca/tests/CSPRNG.Tests.res
--------------------------------------------------------------------------------
/tests/Win32/Debug/TestInsightSettings.ini:
--------------------------------------------------------------------------------
1 | [Config]
2 | BaseUrl=http://MSI:8103
3 |
--------------------------------------------------------------------------------
/tests/Win32/Debug/dunitx-results.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/tests/Win64/Debug/dunitx-results.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------