White paper


This white paper describes the Safe Notes encryption and decryption. Unless otherwise specified then is displayed schematic for the unlimited version of the safenotes subkeys.

Schematic diadram of decription

Generating SafeKey for Decryption

Generating SubKeys for Decryption

Generating Random Data

SafeKey and its Subkeys (version 3.0)
SafeKey and its Subkeys

Safe Notes File Format Specification (version 3.0)
Safe Notes File Format Specification

Safe Notes Clipboard Format Specification (version 3.0)
Safe Notes Clipboard Format Specification



Hash test vectors:
Input: ""
SHA1 : ( DA 39 A3 EE 5E 6B 4B 0D 32 55 BF EF 95 60 18 90 AF D8 07 09 )
RMD160: ( 9C 11 85 A5 C5 E9 FC 54 61 28 08 97 7E E8 F5 48 B2 25 8D 31 )
Tiger2: ( 44 41 BE 75 F6 01 87 73 C2 06 C2 27 45 37 4B 92 4A A8 31 3F EF 91 9F 41 )
SHA256: ( E3 B0 C4 42 98 FC 1C 14 9A FB F4 C8 99 6F B9 24 27 AE 41 E4 64 9B 93 4C A4 95 99 1B 78 52 B8 55 )
RMD320: ( 22 D6 5D 56 61 53 6C DC 75 C1 FD F5 C6 DE 7B 41 B9 F2 73 25 EB C6 1E 85 57 17 7D 70 5A 0E C8 80 15 1C 3A 32 A0 08 99 B8 )
SHA512: ( CF 83 E1 35 7E EF B8 BD F1 54 28 50 D6 6D 80 07 D6 20 E4 05 0B 57 15 DC 83 F4 A9 21 D3 6C E9 CE 47 D0 D1 3C 5D 85 F2 B0 FF 83 18 D2 87 7E EC 2F 63 B9 31 BD 47 41 7A 81 A5 38 32 7A F9 27 DA 3E )

Input: "The quick brown fox jumps over the lazy dog"
SHA1 : ( 2F D4 E1 C6 7A 2D 28 FC ED 84 9E E1 BB 76 E7 39 1B 93 EB 12 )
RMD160: ( 37 F3 32 F6 8D B7 7B D9 D7 ED D4 96 95 71 AD 67 1C F9 DD 3B )
Tiger2: ( 97 6A BF F8 06 2A 2E 9D CE A3 A1 AC E9 66 ED 9C 19 CB 85 55 8B 49 76 D8 )
SHA256: ( D7 A8 FB B3 07 D7 80 94 69 CA 9A BC B0 08 2E 4F 8D 56 51 E4 6D 3C DB 76 2D 02 D0 BF 37 C9 E5 92 )
RMD320: ( E7 66 0E 67 54 94 35 C6 21 41 E5 1C 9A B1 DC C3 B1 EE 9F 65 C0 B3 E5 61 AE 8F 58 C5 DB A3 D2 19 97 78 1C D1 CC 6F BC 34 )
SHA512: ( 07 E5 47 D9 58 6F 6A 73 F7 3F BA C0 43 5E D7 69 51 21 8F B7 D0 C8 D7 88 A3 09 D7 85 43 6B BB 64 2E 93 A2 52 A9 54 F2 39 12 54 7D 1E 8A 3B 5E D6 E1 BF D7 09 78 21 23 3F A0 53 8F 3D B8 54 FE E6 )

Input: 1 million times "a"
SHA1 : ( 34 AA 97 3C D4 C4 DA A4 F6 1E EB 2B DB AD 27 31 65 34 01 6F )
RMD160: ( 52 78 32 43 C1 69 7B DB E1 6D 37 F9 7F 68 F0 83 25 DC 15 28 )
Tiger2: ( E0 68 28 1F 06 0F 55 16 28 CC 57 15 B9 D0 22 67 96 91 4D 45 F7 71 7C F4 )
SHA256: ( CD C7 6E 5C 99 14 FB 92 81 A1 C7 E2 84 D7 3E 67 F1 80 9A 48 A4 97 20 0E 04 6D 39 CC C7 11 2C D0 )
RMD320: ( BD EE 37 F4 37 1E 20 64 6B 8B 0D 86 2D DA 16 29 2A E3 6F 40 96 5E 8C 85 09 E6 3D 1D BD DE CC 50 3E 2B 63 EB 92 45 BB 66 )
SHA512: ( E7 18 48 3D 0C E7 69 64 4E 2E 42 C7 BC 15 B4 63 8E 1F 98 B1 3B 20 44 28 56 32 A8 03 AF A9 73 EB DE 0F F2 44 87 7E A6 0A 4C B0 43 2C E5 77 C3 1B EB 00 9C 5C 2C 49 AA 2E 4E AD B2 17 AD 8C C0 9B )


HMAC test vectors:
Input: message="" key=""
HMAC SHA1: ( FB DB 1D 1B 18 AA 6C 08 32 4B 7D 64 B7 1F B7 63 70 69 0E 1D )
HMAC RMD160: ( 44 D8 6B 65 8A 3E 7C BC 1A 20 10 84 8B 53 E3 5C 91 77 20 CA )
HMAC Tiger2: ( 19 73 0A A3 A7 F4 D1 15 2A B3 39 7C 33 46 CC 19 5E CC 42 A4 A6 0B 53 FD )
HMAC SHA256: ( B6 13 67 9A 08 14 D9 EC 77 2F 95 D7 78 C3 5F C5 FF 16 97 C4 93 71 56 53 C6 C7 12 14 42 92 C5 AD )
HMAC RMD320: ( 9E 16 B9 9B AB B1 D4 9E E2 E6 21 F1 E7 71 89 25 12 FF 3C 24 64 F7 40 11 9D E0 3D DC 9A 56 3A A4 73 E7 5B C2 68 29 AE EE )
HMAC SHA512: ( B9 36 CE E8 6C 9F 87 AA 5D 3C 6F 2E 84 CB 5A 42 39 A5 FE 50 48 0A 6E C6 6B 70 AB 5B 1F 4A C6 73 0C 6C 51 54 21 B3 27 EC 1D 69 40 2E 53 DF B4 9A D7 38 1E B0 67 B3 38 FD 7B 0C B2 22 47 22 5D 47 )

Input: message="what do ya want for nothing?" key="Jefe"
HMAC SHA1: ( EF FC DF 6A E5 EB 2F A2 D2 74 16 D5 F1 84 DF 9C 25 9A 7C 79 )
HMAC RMD160: ( DD A6 C0 21 3A 48 5A 9E 24 F4 74 20 64 A7 F0 33 B4 3C 40 69 )
HMAC Tiger2: ( 6E BE 22 54 70 66 51 95 D7 E7 0D 77 DC 21 83 2C 41 2B 78 22 27 4B D4 C0 )
HMAC SHA256: ( 5B DC C1 46 BF 60 75 4E 6A 04 24 26 08 95 75 C7 5A 00 3F 08 9D 27 39 83 9D EC 58 B9 64 EC 38 43 )
HMAC RMD320: ( E4 40 B0 0B 63 26 E4 F7 DA D3 A6 59 1E 81 89 E9 70 8F C1 7E 3C AB 30 6F C6 7E FA F7 09 47 AA D2 EA 89 E2 8F 79 D0 3B D3 )
HMAC SHA512: ( 16 4B 7A 7B FC F8 19 E2 E3 95 FB E7 3B 56 E0 A3 87 BD 64 22 2E 83 1F D6 10 27 0C D7 EA 25 05 54 97 58 BF 75 C0 5A 99 4A 6D 03 4F 65 F8 F0 E6 FD CA EA B1 A3 4D 4A 6B 4B 63 6E 07 0A 38 BC E7 37 )


PBKDF2 test vectors:
Input: password="password" salt="salt" iterations=4096 dkLen=20
PBKDF2 SHA1: ( 4b 00 79 01 b7 65 48 9a be ad 49 d9 26 f7 21 d0 65 a4 29 c1 )
Input: password="password" salt="salt" iterations=16777216 dkLen=20
PBKDF2 SHA1: ( ee fe 3d 61 cd 4d a4 e4 e9 94 5b 3d 6b a2 15 8c 26 34 e9 84 )
Input: password="passwordPASSWORDpassword" salt="saltSALTsaltSALTsaltSALTsaltSALTsalt" iterations=4096 dkLen=25
PBKDF2 SHA1: ( 3d 2e ec 4f e4 1c 84 9b 80 c8 d8 36 62 c0 e4 4a 8b 29 1a 96 4c f2 f0 70 38 )
Input: password="pass\0word" salt="sa\0lt" iterations=4096 dkLen=16
PBKDF2 SHA1: ( 56 fa 6a a7 55 48 09 9d cc 37 d7 f0 34 25 e0 c3 )

Input: password="pa\0ss" salt="sa\0lt" iterations=320 dkLen=28
PBKDF2-SHA1: ( 2F 77 FE AB 3D 33 0E 50 03 C0 38 05 60 74 98 21 35 26 CD D9 27 A1 A6 5D 89 5F 5C C1 )
PBKDF2-RMD160: ( A8 7B 54 3C 08 74 91 D5 62 A5 5F B6 4C 80 38 0B 82 22 92 C6 E2 AB 38 3D 25 1C F3 3E )
Input: password="pa\0ss" salt="sa\0lt" iterations=320 dkLen=32
PBKDF2-Tiger2: ( B3 50 BE 8C 13 D4 1C 65 47 5F F6 AA 25 FD DB EA D7 13 7E 24 39 2B 4F 83 AB ED C5 74 6B DE 4F 24 )
Input: password="pa\0ss" salt="sa\0lt" iterations=320 dkLen=40
PBKDF2-SHA256: ( B9 D2 72 2D 7E 0E 48 5C FD 89 A6 7A CE 9C 60 9C D7 7D C8 D7 EE ED 27 5B 1B E3 FB BF EF AF 33 19 6D EF CE 54 86 C3 2C 6B )
Input: password="pa\0ss" salt="sa\0lt" iterations=320 dkLen=48
PBKDF2-RMD320: ( 4D C1 7C 66 8E 79 C9 29 23 E6 AD 02 CC 89 14 95 D9 AE 4D 27 8D AF 59 5D 21 E3 D0 2A 40 12 2D F3 DC 4B 97 A4 48 89 CE 7D C3 0C 74 EC CE 30 44 F6 )
Input: password="pa\0ss" salt="sa\0lt" iterations=320 dkLen=72
PBKDF2-SHA512: ( 00 EC 72 AC 46 7F AF EF 7D A3 68 68 FA 38 2A 1D 47 65 7D F6 51 48 7F 72 4C 01 E9 6F 9C 55 60 31 81 BA 96 4D 6E A0 A5 56 C6 80 E6 0C 41 14 68 1C 36 61 2A DB 9A 0D 5E 9C 98 9F 9A 0E A2 07 D1 0A 15 2C 16 EA 61 5C A4 E3 )


PBKDF2-chain, SafeCrypt, Safehash test vectors:
Input: password="pa\0ss" salt="sa\0lt" iterations=7 repeating=5 OutLen=72
PBKDF2-Chain: ( E3 31 04 A3 7F 00 97 ED A1 C7 30 EF B2 2D 5D 0A 51 89 F7 CD 97 5B 0A A0 CA FA 2A D5 17 D7 A9 76 D5 B7 4A B4 2A D4 AF 29 5D 92 D0 59 D6 FF 10 92 C4 4E 89 60 D3 DD D8 90 1D F8 A2 F2 1F F3 D8 8C 38 24 86 6E AF 70 0B 9D )
Input: password="pa\0ss" salt="sa\0lt" iterations=7 repeating=5 OutLen=73
PBKDF2-Chain: ( D4 E5 1E 6C 03 90 B3 24 B5 85 40 96 12 22 5F 83 C1 2E 73 51 F1 70 E8 29 79 75 A9 6E CB A9 44 88 EF 4B 66 F4 25 84 A9 D2 1E FE 87 15 F1 3B 38 BB 89 90 DA 56 47 1F 9A C1 00 80 01 6F 6E 5B F0 BE EE FC 4C DC BA 9E 03 AE 37 )

Input: inkey="pa\0sssa\0lt" iterations=256 OutLen=32
SafeCrypt: ( 24 18 A3 35 0B C2 11 7B F2 FE 95 43 E3 94 40 77 3B 87 2C 80 60 AD EF E6 37 6E 5B F2 9A 23 51 04 )
Input: inkey="pa\0sssa\0lt" iterations=256 OutLen=33
SafeCrypt: ( C1 DA 8D 50 19 B5 9D 96 F0 56 A0 D2 B9 F9 E1 4B 24 E7 20 0B 11 DC CA 52 94 CE 0E 24 EB 7A 08 35 C3 )

Input: inkey="pa\0sssa\0lt"
SafeHash: ( 76 3D 7A 8B 11 47 20 69 55 85 93 60 59 83 40 E6 10 2C CB 92 C5 5F 46 53 8E 66 CF 4B 9C 16 82 7B ED 73 2E B1 91 EE 97 E9 0D 68 10 4E 66 E1 81 09 8F F1 73 A1 BE 5E 09 81 17 8A 18 E8 C2 86 EB 7A 26 6C 4B E5 AC B9 B3 C3 07 9C E3 9D 46 75 B8 CF 78 FF 68 B3 30 DE 59 4F 84 42 F7 79 61 86 56 07 88 3A 08 50 C1 C3 9D 16 D3 A9 14 37 44 B8 2D 0B F5 27 C2 BB 22 63 3D 86 7B FA 60 82 79 FC 7E 02 BB E2 E3 9B C2 50 6B B8 D8 AB D4 75 99 0C AD F7 38 15 EE 5D 96 CF 5D BC 5D 43 8C D5 BA 06 AF 3F 46 CF 98 85 CC 40 23 74 9D 51 1C 08 FB 9E 97 E0 1C AD A6 ED 75 65 D0 9B 90 C7 FE D9 12 B0 00 9D 7A F7 00 9D C6 B9 4E 78 45 33 62 51 8A A0 30 9E B4 9E 0F CB 8D 08 07 D2 EA 6C 65 55 1D 11 72 25 7F 63 F7 D4 A0 E4 88 6F B2 62 31 83 39 6F 1E E6 C4 E0 6C 01 B5 57 5C F1 6E 1B 34 97 5C AA 87 )
Input: inkey="pa\0sssa\0lt\0"
SafeHash: ( 75 BE 04 DF E4 EC E2 75 7B A4 04 9C 49 6A F4 D9 FB D8 89 5C 6A B3 10 D9 0F 7B 48 AC 69 52 4D 5F 36 3F 04 36 C5 DE 23 A1 BF BC BB 6E 93 5B 1A DD CF 8C 0B D8 BA B3 56 AD 15 67 FA E5 49 3C 31 72 54 4B 8D 4E 54 68 17 8B 54 E3 5E 9C 56 D5 B8 1A B3 21 44 18 F0 01 20 0C C0 E1 02 AE 44 AD 78 97 B1 71 AD A9 84 26 8E E8 E4 D7 F9 04 AC FA A5 C9 F1 2F 3F CF 74 45 CF 65 1D A8 CD C2 B7 D1 05 1A EE F3 52 E9 6E 9B C4 6A 87 CD 0A 17 90 CE E9 D1 6B 8C 97 5E A3 83 CB FC 36 16 52 09 61 46 A7 D7 D6 74 E1 27 A1 5A C8 E5 8A 16 8F 6C B9 10 44 3A 8C 52 3B B7 25 23 C6 FB 95 77 A5 72 2A 18 8E 08 30 BC 3F 4B 7D 2E E0 60 B1 A7 CA 50 BC 16 E3 83 EE 31 9A 8B CC 95 A6 BA D2 92 40 30 5A 5A 3B FE 01 13 6D 5D 69 E3 BC 48 B6 D9 49 2D F7 21 2C BC 60 22 8C FF A8 FA 1D FA 3C AF C9 70 8C 4D 09 )

Notice: "Aa\0Bb\0" = ( 41 61 00 42 62 00 )


Description of all algorithms:

Used Pascal style pseudocode in description of algorithms.


PBKDF and ciphers:
BCrypt, PBKDF2 and PBKDF-Schneier are as standard defined functions with these names.
AES, Blowfish, CAST6, IDEA, Serpent, Twofish are as standard defined ciphers with these names, used with maximum security settings.


Subkeys reduction
// According to the type of license change length of subkeys
procedure SetKeys(key_length: integer; var KEY2, KEY2Salt: AnsiString);
begin
if key_length>=1024 then exit; // 1024 bit or more => unchanged
KEY2:=SafeReduceLength(KEY2, key_length div 8);
KEY2Salt:=PBKDF2_Chain(KEY2, '', 2, 3, 512);
end;


PBKDF2-Chain, PBKDF2x, SafeReduceLength:

function PBKDF2_Chain(InHash,Salt:AnsiString; Iteration, Repeating, Out_Len:integer):AnsiString;
var
Hx,H1,H2,H3,H4,H5,H6: AnsiString; i,j: Integer;
begin
SetLength(Hx, Out_Len); fillchar(Hx[1], Out_Len, #0); if Repeating<1 then Repeating:=1;
for j:=1 to Repeating do
begin
H1:=PBKDF2x(TFC_sha1, InHash, Salt, Iteration, Out_Len);
H2:=PBKDF2x(TFC_ripemd160, InHash+H1, Salt, Iteration, Out_Len);
H3:=PBKDF2x(TFC_Tiger, InHash+H1+H2, Salt, Iteration, Out_Len);
H4:=PBKDF2x(TFC_sha256, InHash+H1+H2+H3, Salt, Iteration, Out_Len);
H5:=PBKDF2x(TFC_ripemd320, InHash+H1+H2+H3+H4, Salt, Iteration, Out_Len);
H6:=PBKDF2x(TFC_sha512, InHash+H1+H2+H3+H4+H5, Salt, Iteration, Out_Len);
for i := 1 to Out_Len do
Hx[i] := chr(ord(Hx[i]) xor ord(H1[i]) xor ord(H2[i]) xor ord(H3[i]) xor ord(H4[i]) xor ord(H5[i]) xor ord(H6[i]));
Salt:=Hx;
end;
Result:=Hx;
end;


function PBKDF2x(HashType: TFC_Hashclass; Password, Salt: AnsiString; const C: Integer; const dkLen: Integer): AnsiString;
// for correction weak point of original PBKDF2
var blocksize: word;
begin
blocksize:=HashType.GetBlockSize; // 64 or 128 bytes
if length(Password)>blocksize then Password:=SafeReduceLength(Password, blocksize);
PBKDF2x:=PBKDF2(HashType, Password, Salt, C, dkLen);
end;


function SafeReduceLength(InStr:AnsiString;OutLen:integer):AnsiString;
var i,k: longint;
begin
k:=0;
for i:=OutLen+1 to Length(InStr) do
begin
inc(k); if k>OutLen then k:=1;
InStr[k]:=char(byte(InStr[k]) xor byte(InStr[i]));
end;
Result:=copy(InStr,1,OutLen);
end;


SafeCrypt:
function SafeCrypt(InKey: AnsiString; Iteration, OutLen:integer): AnsiString;
const KeyLength=512;
var i,PKx:longint; Kx,ActKey,ActOut,Salt:AnsiString;
begin
Salt:=SafeHash(InKey);
ActOut:= PBKDF2_Chain(InKey, Salt, 2,3, KeyLength+OutLen);
ActKey:= PBKDF2_Chain(Salt+InKey, ActOut, 2,3, KeyLength);
PKx:=OutLen+1;
if Iteration>1 then Iteration:=Iteration div 2 else Iteration:=1;
for i:=1 to Iteration do
begin
Kx:=copy(ActOut,PKx,KeyLength);
EncryptString({text, key512} ActKey, Kx ); // Out 512 bytes -> key
DecryptString({text, key512} ActOut, ActKey ) // Out 512+OutLen bytes -> text
// Encryption with cascade: Blowfish-AES-Twofish-Serpent-CAST6-IDEA
end;
Result:=SafeReduceLength(ActOut, OutLen);
end;

Encryption:
procedure EncryptString(var Text:AnsiString; SKeys:AnsiString);
begin // Every procedure use different sections of the SKeys (4096-bit) as IV and Key
if length(SKeys)<>512 then SKeys:=PBKDF2_Chain(SKeys,SKeys, 2,3, 512);
Encrypt_BlowFish(Text, SKeys);
Encrypt_AES(Text, SKeys);
Encrypt_TwoFish(Text, SKeys);
Encrypt_Serpent(Text, SKeys);
Encrypt_Cast6(Text, SKeys);
Encrypt_Idea(Text, SKeys);
end;

procedure DecryptString(var Text:AnsiString; SKeys:AnsiString);
begin // Every procedure use different sections of the SKeys (4096-bit) as IV and Key
if length(SKeys)<>512 then SKeys:=PBKDF2_Chain(SKeys,SKeys, 2,3, 512);
Decrypt_Idea(Text, SKeys);
Decrypt_Cast6(Text, SKeys);
Decrypt_Serpent(Text, SKeys);
Decrypt_TwoFish(Text, SKeys);
Decrypt_AES(Text, SKeys);
Decrypt_BlowFish(Text, SKeys);
end;


SafeHash:
function SafeHash(const pwd: AnsiString): AnsiString;
var
key:AnsiString;
begin
key:='';
Result:=GetHMAC3(key,pwd,320);
end;

GetHMAC3:
function GetHMAC3(const Key, Msg:AnsiString; OutBytes:integer): AnsiString;
// replacement for HMAC (eg. HMAC-SHA512), this is much safer
var
T,H,H1,H2,H3,H4,H5,H6: AnsiString;
begin
T:=Key+Msg;
H1:=HashSHA1(T);
T:=H1+T;
H2:=HashRMD160(T);
T:=H2+T;
H3:=HashTiger(T);
T:=H3+T;
H4:=HashSHA256(T);
T:=H4+T;
H5:=HashRMD320(T);
T:=H5+T;
H6:=HashSHA512(T);
H :=H6+H5+H4+H3+H2+H1;
while length(H) <(OutBytes * 3) do
begin
H1:=HashSHA1(H);
H:=H1+H;
H2:=HashRMD160(H);
H:=H2+H;
H3:=HashTiger(H);
H:=H3+H;
H4:=HashSHA256(H);
H:=H4+H;
H5:=HashRMD320(H);
H:=H5+H;
H6:=HashSHA512(H);
H :=H6+H;
end;
Result:=SafeReduceLength(H,OutBytes);
end;

Functions for creating random data:
function ComputePublicMasterKey(PMKSource: AnsiString): AnsiString;
begin
Result:=PBKDF2_Chain(PMKSource, 'PublicMasterKey', 2,3, 512);
Result:=SafeReduceLength(Result,16);
AddToEncryptedLOG(fLogPMK,PMKSource,Result); // This allows control of safety (no back-door in random data)
end;

function ComputeSalt(SaltSource: AnsiString): AnsiString;
begin
Result:=PBKDF2_Chain(SaltSource, 'Salt', 2,3, 32);
AddToEncryptedLOG(fLogSALT,SaltSource,Result); // This allows control of safety (no back-door in random data)
end;

PBKDF3:
// replacement for PBKDF2, this is much much more safer
// used only in customversions


Bitcoin Wallet functions:

function RandomSourceToPrivatKey(S: AnsiString): AnsiString;
begin
S:=SafeReduceLength(HashSHA512(S)+HashRMD320(S)+HashTiger(S)+HashRMD160(S)+HashSHA256(S),64)+S; // S is a random Source: 512-bit binary data or 24 words
if UltraSafeFlag then Password:=S[47]+S[53]+S[61]+S[3]+S[7]+S[11]+S[17]+S[19]+S[29]+S[31]+S[41]+S[43]+S[2]+S[37]+S[59]+S[5]+S[23]+S[13];
Result:=SafeReduceLength(HashSHA512(S)+HashRMD320(S)+HashTiger(S)+HashRMD160(S)+HashSHA256(S),32);
if UltraSafeFlag then EncryptString(Result, Password); // Safe vs UltraSafe difference: this code; and Ultra has a stronger quality tests for randomness
end;

function PrivatKeyToBitcoinAddress(PrivateKey: AnsiString): AnsiString;
begin
PublicKey:=ECC_PrivatKeytoPublicKey(Privatkey, CurveParam); // Elliptic-curve cryptography, Bitcoin use Secp256k1 curve
Result:=PublicKeyToBTCAdr(PublicKey, CompressFlag); // Bitcoin address, compressed or uncompressed
end;

function RandomPoolToRandomSource(PoolData: AnsiString): AnsiString;
begin
repeat
RandomSeed:=GetRandomData(Randompool); // RandomSeed is a random sequence (512-bit) created from RandomPool with strong cryptography. Random Pool is remixed and increased with new random data
RandomWords:=Create24Words(RandomSeed); // 24 words from RandomSeed, lowercase with space as a separator
if UseWordsFlag then RandomSource:=RandomWords else RandomSource:=RandomSeed;
IsGood:=Test(RandomSource, UltraSafeFlag); // if UltraSafe then is used a stronger quality tests for randomness
until IsGood;
Result:= RandomSource;
end;

.....

Information: We are working on the content of this page. Page under construction...