Skip to content

Commit

Permalink
Improves random generation and adds UUID
Browse files Browse the repository at this point in the history
  • Loading branch information
dipu-bd committed Sep 18, 2024
1 parent d904c66 commit 91a945a
Show file tree
Hide file tree
Showing 31 changed files with 1,550 additions and 397 deletions.
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
# 1.21.0

- Moves random generators outside of the base package; `import 'package:hashlib/random.dart';`
- Introduces UUID generators. Example: `uuid.v4()`

# 1.20.4

- Ensure seed uniqueness in `RandomGenerators` across Isolates

# 1.20.3

- Exports hashlib_codecs from current package. To get it: `import 'package:hashlib/codecs.dart';`
- Exports hashlib_codecs from current package; `import 'package:hashlib/codecs.dart';`

# 1.20.2

Expand Down
95 changes: 78 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,11 @@ There is only 1 dependency used by this package:
| CRC | `crc16`, `crc32`, `crc64` | Wikipedia |
| Alder32 | `alder32` | Wikipedia |

### Random Number Generation
### Random Algorithm

Available generators:
#### Random number generators

Accessible through `HashlibRandom`:

- secure
- system
Expand All @@ -81,6 +83,18 @@ Available generators:
- xxh64
- sm3

#### UUID generators

Accessible through `uuid`

- v1
- v3
- v4
- v5
- v6
- v7
- v8

## Demo

A demo application is available in Google Play Store featuring the capabilities of this package.
Expand All @@ -103,21 +117,26 @@ Check the [API Reference](https://pub.dev/documentation/hashlib/latest/) for det

Examples can be found inside the `example` folder.

### Hashilb Example

```dart
import 'package:hashlib/codecs.dart';
import 'package:hashlib/hashlib.dart';
void main() {
var text = "Happy Hashing!";
var key = "password";
var pw = key.codeUnits;
var iv = "some salt".codeUnits;
print("text => $text");
final key = "password";
final salt = "some salt";
print("key => $key");
print("salt => ${toHex(iv)}");
print("salt => $salt");
print('');
// Example of hash code generations
final pw = key.codeUnits;
final iv = salt.codeUnits;
// Example of hash-code generations
print('XXH32 => ${xxh32code(text)}');
print('CRC32 => ${crc32code(text)}');
print('Alder32 => ${alder32code(text)}');
Expand Down Expand Up @@ -163,35 +182,77 @@ void main() {
print("BLAKE-2b-MAC/224 => ${Blake2b(28).mac.by(pw).string(text)}");
print('');
// Examples of PBKDF2 key derivation
print("SHA256/HMAC/PBKDF2 => ${pbkdf2(pw, iv).hex()}");
print("BLAKE2b-256/HMAC/PBKDF2 => ${blake2b256.pbkdf2(iv).hex(pw)}");
print("BLAKE2b-256/MAC/PBKDF2 => ${blake2b256.mac.pbkdf2(iv).hex(pw)}");
print("SHA1/HMAC/PBKDF2 => ${sha1.pbkdf2(iv, iterations: 100).hex(pw)}");
print('');
// Examples of OTP generation
int nw = DateTime.now().millisecondsSinceEpoch ~/ 30000;
var counter = fromHex(nw.toRadixString(16).padLeft(16, '0'));
print('TOTP[time=$nw] => ${TOTP(iv).value()}');
print('HOTP[counter=$nw] => ${HOTP(iv, counter: counter).value()}');
print('');
}
```

### Key Generation Example

```dart
import 'package:hashlib/hashlib.dart';
void main() {
final key = "password";
final salt = "some salt";
print("key => $key");
print("salt => $salt");
print('');
final pw = key.codeUnits;
final iv = salt.codeUnits;
// Examples of Argon2 key derivation
var argon2Test = Argon2Security.test;
final argon2Test = Argon2Security.test;
print("[Argon2i] => ${argon2i(pw, iv, security: argon2Test)}");
print("[Argon2d] => ${argon2d(pw, iv, security: argon2Test)}");
print("[Argon2id] => ${argon2id(pw, iv, security: argon2Test)}");
// Examples of scrypt key derivation
var scryptLittle = ScryptSecurity.little;
final scryptLittle = ScryptSecurity.little;
print("[scrypt] => ${scrypt(pw, iv, security: scryptLittle, dklen: 24)}");
print('');
// Examples of bcrypt key derivation
var bcryptLittle = BcryptSecurity.little;
final bcryptLittle = BcryptSecurity.little;
print("[bcrypt] => ${bcrypt(pw, bcryptSalt(security: bcryptLittle))}");
print('');
// Examples of PBKDF2 key derivation
print("SHA256/HMAC/PBKDF2 => ${pbkdf2(pw, iv).hex()}");
print("BLAKE2b-256/HMAC/PBKDF2 => ${blake2b256.pbkdf2(iv).hex(pw)}");
print("BLAKE2b-256/MAC/PBKDF2 => ${blake2b256.mac.pbkdf2(iv).hex(pw)}");
print("SHA1/HMAC/PBKDF2 => ${sha1.pbkdf2(iv, iterations: 100).hex(pw)}");
print('');
}
```

### Random Example

```dart
import 'package:hashlib/codecs.dart';
import 'package:hashlib/random.dart';
void main() {
print('UUID Generation:');
print('UUIDv1: ${uuid.v1()}');
print('UUIDv3: ${uuid.v3()}');
print('UUIDv4: ${uuid.v4()}');
print('UUIDv5: ${uuid.v5()}');
print('UUIDv6: ${uuid.v6()}');
print('UUIDv7: ${uuid.v7()}');
print('UUIDv8: ${uuid.v8()}');
print('');
print('Random Generation:');
print(randomNumbers(4));
print(toHex(randomBytes(16)));
print(randomString(32, lower: true, whitelist: '_'.codeUnits));
print('');
}
```

Expand Down
1 change: 1 addition & 0 deletions benchmark/bcrypt.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import 'dart:math';

import 'package:hashlib/hashlib.dart';
import 'package:hashlib/random.dart';

import '_base.dart';

Expand Down
2 changes: 1 addition & 1 deletion benchmark/random.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import 'dart:math';

import 'package:hashlib/hashlib.dart';
import 'package:hashlib/random.dart';

import '_base.dart';

Expand Down
36 changes: 8 additions & 28 deletions example/hashlib_example.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,18 @@ import 'package:hashlib/hashlib.dart';

void main() {
var text = "Happy Hashing!";
var key = "password";
var pw = key.codeUnits;
var iv = "some salt".codeUnits;
print("text => $text");

final key = "password";
final salt = "some salt";
print("key => $key");
print("salt => ${toHex(iv)}");
print("salt => $salt");
print('');

// Example of hash code generations
final pw = key.codeUnits;
final iv = salt.codeUnits;

// Example of hash-code generations
print('XXH32 => ${xxh32code(text)}');
print('CRC32 => ${crc32code(text)}');
print('Alder32 => ${alder32code(text)}');
Expand Down Expand Up @@ -57,33 +60,10 @@ void main() {
print("BLAKE-2b-MAC/224 => ${Blake2b(28).mac.by(pw).string(text)}");
print('');

// Examples of PBKDF2 key derivation
print("SHA256/HMAC/PBKDF2 => ${pbkdf2(pw, iv).hex()}");
print("BLAKE2b-256/HMAC/PBKDF2 => ${blake2b256.pbkdf2(iv).hex(pw)}");
print("BLAKE2b-256/MAC/PBKDF2 => ${blake2b256.mac.pbkdf2(iv).hex(pw)}");
print("SHA1/HMAC/PBKDF2 => ${sha1.pbkdf2(iv, iterations: 100).hex(pw)}");
print('');

// Examples of OTP generation
int nw = DateTime.now().millisecondsSinceEpoch ~/ 30000;
var counter = fromHex(nw.toRadixString(16).padLeft(16, '0'));
print('TOTP[time=$nw] => ${TOTP(iv).value()}');
print('HOTP[counter=$nw] => ${HOTP(iv, counter: counter).value()}');
print('');

// Examples of Argon2 key derivation
var argon2Test = Argon2Security.test;
print("[Argon2i] => ${argon2i(pw, iv, security: argon2Test)}");
print("[Argon2d] => ${argon2d(pw, iv, security: argon2Test)}");
print("[Argon2id] => ${argon2id(pw, iv, security: argon2Test)}");

// Examples of scrypt key derivation
var scryptLittle = ScryptSecurity.little;
print("[scrypt] => ${scrypt(pw, iv, security: scryptLittle, dklen: 24)}");
print('');

// Examples of bcrypt key derivation
var bcryptLittle = BcryptSecurity.little;
print("[bcrypt] => ${bcrypt(pw, bcryptSalt(security: bcryptLittle))}");
print('');
}
35 changes: 35 additions & 0 deletions example/keygen_example.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import 'package:hashlib/hashlib.dart';

void main() {
final key = "password";
final salt = "some salt";
print("key => $key");
print("salt => $salt");
print('');

final pw = key.codeUnits;
final iv = salt.codeUnits;

// Examples of Argon2 key derivation
final argon2Test = Argon2Security.test;
print("[Argon2i] => ${argon2i(pw, iv, security: argon2Test)}");
print("[Argon2d] => ${argon2d(pw, iv, security: argon2Test)}");
print("[Argon2id] => ${argon2id(pw, iv, security: argon2Test)}");

// Examples of scrypt key derivation
final scryptLittle = ScryptSecurity.little;
print("[scrypt] => ${scrypt(pw, iv, security: scryptLittle, dklen: 24)}");
print('');

// Examples of bcrypt key derivation
final bcryptLittle = BcryptSecurity.little;
print("[bcrypt] => ${bcrypt(pw, bcryptSalt(security: bcryptLittle))}");
print('');

// Examples of PBKDF2 key derivation
print("SHA256/HMAC/PBKDF2 => ${pbkdf2(pw, iv).hex()}");
print("BLAKE2b-256/HMAC/PBKDF2 => ${blake2b256.pbkdf2(iv).hex(pw)}");
print("BLAKE2b-256/MAC/PBKDF2 => ${blake2b256.mac.pbkdf2(iv).hex(pw)}");
print("SHA1/HMAC/PBKDF2 => ${sha1.pbkdf2(iv, iterations: 100).hex(pw)}");
print('');
}
20 changes: 20 additions & 0 deletions example/random_example.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import 'package:hashlib/codecs.dart';
import 'package:hashlib/random.dart';

void main() {
print('UUID Generation:');
print('UUIDv1: ${uuid.v1()}');
print('UUIDv3: ${uuid.v3()}');
print('UUIDv4: ${uuid.v4()}');
print('UUIDv5: ${uuid.v5()}');
print('UUIDv6: ${uuid.v6()}');
print('UUIDv7: ${uuid.v7()}');
print('UUIDv8: ${uuid.v8()}');
print('');

print('Random Generation:');
print(randomNumbers(4));
print(toHex(randomBytes(16)));
print(randomString(32, lower: true, whitelist: '_'.codeUnits));
print('');
}
8 changes: 8 additions & 0 deletions lib/random.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Copyright (c) 2024, Sudipto Chandra
// All rights reserved. Check LICENSE file for details.

/// Implementation of secure random generators based on hashlib
library hashlib_random;

export 'package:hashlib/src/random.dart';
export 'package:hashlib/src/uuid.dart';
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
// Copyright (c) 2024, Sudipto Chandra
// All rights reserved. Check LICENSE file for details.

import 'dart:js' show context;
import 'dart:async';
import 'dart:math' show Random;

const int _mask32 = 0xFFFFFFFF;

int _seedCounter = context.hashCode;
int _seedCounter = Zone.current.hashCode;

@pragma('vm:prefer-inline')
Random secureRandom() => Random($generateSeed());
final _secure = Random($generateSeed());

Random secureRandom() => _secure;

int $generateSeed() {
int code = DateTime.now().microsecondsSinceEpoch;
int code = DateTime.now().millisecondsSinceEpoch;
code -= _seedCounter++;
if (code.bitLength & 1 == 1) {
code *= ~code;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ import 'dart:math' show Random;

const int _mask32 = 0xFFFFFFFF;

final secure = Random.secure();
final _secure = Random.secure();

@pragma('vm:prefer-inline')
Random secureRandom() => secure;
Random secureRandom() => _secure;

@pragma('vm:prefer-inline')
int $generateSeed() =>
(DateTime.now().microsecondsSinceEpoch & _mask32) ^ secure.nextInt(_mask32);
(DateTime.now().microsecondsSinceEpoch & _mask32) ^
_secure.nextInt(_mask32);
Loading

0 comments on commit 91a945a

Please sign in to comment.