update dependencies

This commit is contained in:
otsmr 2026-02-07 23:12:41 +01:00
parent 7930d97270
commit 3a3a7e5a63
35 changed files with 1353 additions and 1134 deletions

View file

@ -3,17 +3,17 @@ dots_indicator: 508f5883ac79bdbc10254092de3f28f571d261cd
ed25519_edwards: 7353ba759ea9f4646cbf481c2ef949625c8ce4cf ed25519_edwards: 7353ba759ea9f4646cbf481c2ef949625c8ce4cf
flutter_sharing_intent: aa1672f547d6579585fa27df0b28ffa2a2544aaa flutter_sharing_intent: aa1672f547d6579585fa27df0b28ffa2a2544aaa
hand_signature: 1beedb164d093643365b0832277c377353c7464f hand_signature: 1beedb164d093643365b0832277c377353c7464f
hashlib: 983cdbd5ee2529b908876b57a7217c09c6bc148a hashlib: bc9c2f8dd7bbc72f47ccab0ce1111d40259c49bc
hashlib_codecs: 2a966c37c3b9b1f5541ae88e99ab34acf3fc968b hashlib_codecs: 2a966c37c3b9b1f5541ae88e99ab34acf3fc968b
introduction_screen: 4a90e557630b28834479ed9c64a9d2d0185d8e48 introduction_screen: 4a90e557630b28834479ed9c64a9d2d0185d8e48
libsignal_protocol_dart: 618f0c0b49534245a640a31d204265440cbac9ee libsignal_protocol_dart: 618f0c0b49534245a640a31d204265440cbac9ee
lottie: 4f1a5a52bdf1e1c1e12fa97c96174dcb05419e19 lottie: 4f1a5a52bdf1e1c1e12fa97c96174dcb05419e19
mutex: 84ca903a3ac863735e3228c75a212133621f680f mutex: 84ca903a3ac863735e3228c75a212133621f680f
no_screenshot: 8e19a8d0e30bd1d5000425cabac7ef3e3da4d5ea no_screenshot: 57b4a072e9193b4fa1257a6f1acb13ef307625e7
optional: 71c638891ce4f2aff35c7387727989f31f9d877d optional: 71c638891ce4f2aff35c7387727989f31f9d877d
photo_view: a13ca2fc387a3fb1276126959e092c44d0029987 photo_view: a13ca2fc387a3fb1276126959e092c44d0029987
pointycastle: bbd8569f68a7fccbdf0b92d0b44a9219c126c8dd pointycastle: bbd8569f68a7fccbdf0b92d0b44a9219c126c8dd
qr: ff808bb3f354e6a7029ec953cbe0144a42021db6 qr: 7b1e9665ca976f484e7975356cf26fc7a0ccf02e
qr_flutter: d5e7206396105d643113618290bbcc755d05f492 qr_flutter: d5e7206396105d643113618290bbcc755d05f492
restart_app: 12339f63bf8e9631e619c4f9f6b4e013fa324715 restart_app: 12339f63bf8e9631e619c4f9f6b4e013fa324715
x25519: ecb1d357714537bba6e276ef45f093846d4beaee x25519: ecb1d357714537bba6e276ef45f093846d4beaee

View file

@ -1,24 +1,38 @@
// Copyright (c) 2024, Sudipto Chandra // Copyright (c) 2025, Sudipto Chandra
// All rights reserved. Check LICENSE file for details. // All rights reserved. Check LICENSE file for details.
import 'dart:async';
import 'dart:math' show Random; import 'dart:math' show Random;
import 'generator_js_legacy.dart'
if (dart.library.js_interop) 'generator_js_interop.dart';
const int _mask32 = 0xFFFFFFFF; const int _mask32 = 0xFFFFFFFF;
int _seedCounter = Zone.current.hashCode; /// For Node.js environment + dart2js compiler
class NodeRandom extends CryptoRandom implements Random {
@override
int nextInt(final int max) {
if (max < 1 || max > _mask32 + 1) {
throw RangeError.range(
max, 1, _mask32 + 1, 'max', 'max must be <= (1 << 32)');
}
return cryptoRandomInt(max);
}
@override
double nextDouble() {
final int first26Bits = nextInt(1 << 26);
final int next27Bits = nextInt(1 << 27);
final int random53Bits = (first26Bits << 27) + next27Bits; // JS int limit
return random53Bits / (1 << 53);
}
@override
bool nextBool() => nextInt(2) == 1;
}
/// Returns a secure random generator in JS runtime /// Returns a secure random generator in JS runtime
Random secureRandom() => Random($generateSeed()); Random secureRandom() => NodeRandom();
/// Generates a random seed in JS runtime /// Generates a random seed
int $generateSeed() { int $generateSeed() => secureRandom().nextInt(_mask32);
int code = DateTime.now().millisecondsSinceEpoch;
code -= _seedCounter++;
if (code.bitLength & 1 == 1) {
code *= ~code;
}
code ^= ~_seedCounter << 5;
_seedCounter += code & 7;
return code & _mask32;
}

View file

@ -0,0 +1,25 @@
// Copyright (c) 2025, Sudipto Chandra
// All rights reserved. Check LICENSE file for details.
import 'dart:js_interop';
@JS()
@staticInterop
class Crypto {}
extension on Crypto {
external int randomInt(final int max);
}
@JS('require')
external Crypto require(final String id);
/// For Node.js environment + dart2js compiler
abstract class CryptoRandom {
Crypto? _crypto;
int cryptoRandomInt(final int max) {
_crypto ??= require('crypto');
return _crypto!.randomInt(max);
}
}

View file

@ -0,0 +1,29 @@
// Copyright (c) 2025, Sudipto Chandra
// All rights reserved. Check LICENSE file for details.
// Dart v2.19 compatible version
// Works with dart2js in a Node.js runtime (where `require` exists).
// ignore_for_file: deprecated_member_use
import 'dart:js' as js;
js.JsObject _require(String id) {
final r = js.context['require'];
if (r == null) {
throw StateError("`require` is not available.");
}
return (r as js.JsFunction).apply([id]) as js.JsObject;
}
/// For Node.js environment + dart2js compiler
abstract class CryptoRandom {
js.JsObject? _crypto;
js.JsFunction? _randomInt;
int cryptoRandomInt(final int max) {
_crypto ??= _require('crypto');
_randomInt ??= _crypto!['randomInt'] as js.JsFunction;
return (_randomInt!.apply([max]) as num).toInt();
}
}

View file

@ -11,6 +11,4 @@ Random secureRandom() => Random.secure();
/// Generates a random seed /// Generates a random seed
@pragma('vm:prefer-inline') @pragma('vm:prefer-inline')
int $generateSeed() => int $generateSeed() => Random.secure().nextInt(_mask32);
(DateTime.now().microsecondsSinceEpoch & _mask32) ^
Random.secure().nextInt(_mask32);

View file

@ -11,8 +11,12 @@ import 'package:hashlib/src/algorithms/sm3.dart';
import 'package:hashlib/src/algorithms/xxh64/xxh64.dart'; import 'package:hashlib/src/algorithms/xxh64/xxh64.dart';
import 'package:hashlib/src/core/hash_base.dart'; import 'package:hashlib/src/core/hash_base.dart';
import 'generator_vm.dart' if (dart.library.js) 'generator_js.dart'; import 'generator_vm.dart'
export 'generator_vm.dart' if (dart.library.js) 'generator_js.dart'; if (dart.library.html) 'generator_vm.dart'
if (dart.library.js) 'generator_js.dart';
export 'generator_vm.dart'
if (dart.library.html) 'generator_vm.dart'
if (dart.library.js) 'generator_js.dart';
const int _mask32 = 0xFFFFFFFF; const int _mask32 = 0xFFFFFFFF;
@ -34,13 +38,13 @@ enum RNG {
case RNG.keccak: case RNG.keccak:
return _keccakGenerateor(seed); return _keccakGenerateor(seed);
case RNG.sha256: case RNG.sha256:
return _hashGenerateor(SHA256Hash(), seed); return _hashGenerator(SHA256Hash(), seed);
case RNG.md5: case RNG.md5:
return _hashGenerateor(MD4Hash(), seed); return _hashGenerator(MD4Hash(), seed);
case RNG.xxh64: case RNG.xxh64:
return _hashGenerateor(XXHash64Sink(111), seed); return _hashGenerator(XXHash64Sink(111), seed);
case RNG.sm3: case RNG.sm3:
return _hashGenerateor(SM3Hash(), seed); return _hashGenerator(SM3Hash(), seed);
case RNG.system: case RNG.system:
return _systemGenerator(seed); return _systemGenerator(seed);
case RNG.secure: case RNG.secure:
@ -115,7 +119,7 @@ NextIntFunction _keccakGenerateor([int? seed]) {
} }
/// Returns a iterable of 32-bit integers generated from the [sink]. /// Returns a iterable of 32-bit integers generated from the [sink].
NextIntFunction _hashGenerateor( NextIntFunction _hashGenerator(
HashDigestSink sink, [ HashDigestSink sink, [
int? seed, int? seed,
]) { ]) {

View file

@ -1,7 +1,7 @@
name: hashlib name: hashlib
description: Secure hash functions, checksum generators, and key derivation algorithms optimized for Dart. description: Secure hash functions, checksum generators, and key derivation algorithms optimized for Dart.
homepage: https://github.com/bitanon/hashlib homepage: https://github.com/bitanon/hashlib
version: 2.2.0 version: 2.3.0
environment: environment:
sdk: '>=2.19.0 <4.0.0' sdk: '>=2.19.0 <4.0.0'

View file

@ -0,0 +1,134 @@
// Copyright (c) 2023, Sudipto Chandra
// All rights reserved. Check LICENSE file for details.
import 'dart:convert';
import 'package:hashlib/hashlib.dart';
import 'package:test/test.dart';
void main() {
group('bcrypt version 2a', () {
// http://cvsweb.openwall.com/cgi/cvsweb.cgi/Owl/packages/glibc/crypt_blowfish/wrapper.c?rev=HEAD
test(r"$2a$06$DCq7YPn5Rq63x1Lad4cll.TV4S6ytwfsfvkgY8jIucDrjc8deX1s.", () {
const password = r"";
const encoded =
r"$2a$06$DCq7YPn5Rq63x1Lad4cll.TV4S6ytwfsfvkgY8jIucDrjc8deX1s.";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
// https://stackoverflow.com/a/12761326/774398
test(r"$2a$10$.TtQJ4Jr6isd4Hp.mVfZeuh6Gws4rOQ/vdBczhDx.19NFK0Y84Dle", () {
const password = r"ππππππππ";
const encoded =
r"$2a$10$.TtQJ4Jr6isd4Hp.mVfZeuh6Gws4rOQ/vdBczhDx.19NFK0Y84Dle";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
// https://bitbucket.org/vadim/bcrypt.net/src/464c41416dc9/BCrypt.Net.Test/TestBCrypt.cs?fileviewer=file-view-default
test(r"$2a$08$HqWuK6/Ng6sg9gQzbLrgb.Tl.ZHfXLhvt/SgVyWhQqgqcZ7ZuUtye", () {
const password = r"";
const encoded =
r"$2a$08$HqWuK6/Ng6sg9gQzbLrgb.Tl.ZHfXLhvt/SgVyWhQqgqcZ7ZuUtye";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2a$06$m0CrhHm10qJ3lXRY.5zDGO3rS2KdeeWLuGmsfGlMfOxih58VYVfxe", () {
const password = r"a";
const encoded =
r"$2a$06$m0CrhHm10qJ3lXRY.5zDGO3rS2KdeeWLuGmsfGlMfOxih58VYVfxe";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2a$06$If6bvum7DFjUnE9p2uDeDu0YHzrHM6tf.iqN8.yx.jNN1ILEf7h0i", () {
const password = r"abc";
const encoded =
r"$2a$06$If6bvum7DFjUnE9p2uDeDu0YHzrHM6tf.iqN8.yx.jNN1ILEf7h0i";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2a$06$.rCVZVOThsIa97pEDOxvGuRRgzG64bvtJ0938xuqzv18d3ZpQhstC", () {
const password = r"abcdefghijklmnopqrstuvwxyz";
const encoded =
r"$2a$06$.rCVZVOThsIa97pEDOxvGuRRgzG64bvtJ0938xuqzv18d3ZpQhstC";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2a$06$fPIsBO8qRqkjj273rfaOI.HtSV9jLDpTbZn782DC6/t7qT67P6FfO", () {
const password = r"~!@#$%^&*() ~!@#$%^&*()PNBFRD";
const encoded =
r"$2a$06$fPIsBO8qRqkjj273rfaOI.HtSV9jLDpTbZn782DC6/t7qT67P6FfO";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
// https://github.com/pyca/bcrypt/blob/main/tests/test_bcrypt.py
test(r"$2a$05$CCCCCCCCCCCCCCCCCCCCC.E5YPO9kmyuRGyh0XouQYb4YMJKvyOeW", () {
var password = "U*U";
var encoded =
r"$2a$05$CCCCCCCCCCCCCCCCCCCCC.E5YPO9kmyuRGyh0XouQYb4YMJKvyOeW";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2a$05$CCCCCCCCCCCCCCCCCCCCC.VGOzA784oUp/Z0DY336zx7pLYAy0lwK", () {
var password = "U*U*";
var encoded =
r"$2a$05$CCCCCCCCCCCCCCCCCCCCC.VGOzA784oUp/Z0DY336zx7pLYAy0lwK";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2a$05$XXXXXXXXXXXXXXXXXXXXXOAcXxm9kjPGEMsLznoKqmqw7tc8WCx4a", () {
var password = "U*U*U";
var encoded =
r"$2a$05$XXXXXXXXXXXXXXXXXXXXXOAcXxm9kjPGEMsLznoKqmqw7tc8WCx4a";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2a$05$abcdefghijklmnopqrstuu5s2v8.iXieOjg/.AySBTTZIIVFJeBui", () {
var password = "0123456789abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
"chars after 72 are ignored";
var encoded =
r"$2a$05$abcdefghijklmnopqrstuu5s2v8.iXieOjg/.AySBTTZIIVFJeBui";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2a$05$/OK.fbVrR/bpIqNJ5ianF.swQOIzjOiJ9GHEPuhEkvqrUyvWhEMx6", () {
var password = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"chars after 72 are ignored as usual";
var encoded =
r"$2a$05$/OK.fbVrR/bpIqNJ5ianF.swQOIzjOiJ9GHEPuhEkvqrUyvWhEMx6";
var output = bcrypt(password.codeUnits, encoded);
expect(output, equals(encoded));
});
test(r"$2a$05$/OK.fbVrR/bpIqNJ5ianF.Sa7shbm4.OzKpvFnX1pQLmQW96oUlCq", () {
var password = "\xa3";
var encoded =
r"$2a$05$/OK.fbVrR/bpIqNJ5ianF.Sa7shbm4.OzKpvFnX1pQLmQW96oUlCq";
var output = bcrypt(password.codeUnits, encoded);
expect(output, equals(encoded));
});
test(r"$2a$04$tecY.9ylRInW/rAAzXCXPOOlyYeCNzmNTzPDNSIFztFMKbvs/s5XG", () {
var password =
"g7\r\x01\xf3\xd4\xd0\xa9JB^\x18\x007P\xb2N\xc7\x1c\xee\x87&\x83C"
"\x8b\xe8\x18\xc5>\x86\x14/\xd6\xcc\x1cJ\xde\xd7ix\xeb\xdeO\xef"
"\xe1i\xac\xcb\x03\x96v1' \xd6@.m\xa5!\xa0\xef\xc0(";
var encoded =
r"$2a$04$tecY.9ylRInW/rAAzXCXPOOlyYeCNzmNTzPDNSIFztFMKbvs/s5XG";
var output = bcrypt(password.codeUnits, encoded);
expect(output, equals(encoded));
});
});
}

View file

@ -0,0 +1,186 @@
// Copyright (c) 2023, Sudipto Chandra
// All rights reserved. Check LICENSE file for details.
import 'dart:convert';
import 'package:hashlib/hashlib.dart';
import 'package:test/test.dart';
void main() {
// https://github.com/pyca/bcrypt/blob/main/tests/test_bcrypt.py
group('bcrypt version 2b', () {
test(r"$2b$04$cVWp4XaNU8a4v1uMRum2SO026BWLIoQMD/TXg5uZV.0P.uO8m3YEm", () {
var password = "Kk4DQuMMfZL9o";
var encoded =
r"$2b$04$cVWp4XaNU8a4v1uMRum2SO026BWLIoQMD/TXg5uZV.0P.uO8m3YEm";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2b$04$pQ7gRO7e6wx/936oXhNjrOUNOHL1D0h1N2IDbJZYs.1ppzSof6SPy", () {
var password = "9IeRXmnGxMYbs";
var encoded =
r"$2b$04$pQ7gRO7e6wx/936oXhNjrOUNOHL1D0h1N2IDbJZYs.1ppzSof6SPy";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2b$04$SQe9knOzepOVKoYXo9xTteNYr6MBwVz4tpriJVe3PNgYufGIsgKcW", () {
var password = "xVQVbwa1S0M8r";
var encoded =
r"$2b$04$SQe9knOzepOVKoYXo9xTteNYr6MBwVz4tpriJVe3PNgYufGIsgKcW";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2b$04$eH8zX.q5Q.j2hO1NkVYJQOM6KxntS/ow3.YzVmFrE4t//CoF4fvne", () {
var password = "Zfgr26LWd22Za";
var encoded =
r"$2b$04$eH8zX.q5Q.j2hO1NkVYJQOM6KxntS/ow3.YzVmFrE4t//CoF4fvne";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2b$04$ahiTdwRXpUG2JLRcIznxc.s1.ydaPGD372bsGs8NqyYjLY1inG5n2", () {
var password = "Tg4daC27epFBE";
var encoded =
r"$2b$04$ahiTdwRXpUG2JLRcIznxc.s1.ydaPGD372bsGs8NqyYjLY1inG5n2";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2b$04$nQn78dV0hGHf5wUBe0zOFu8n07ZbWWOKoGasZKRspZxtt.vBRNMIy", () {
var password = "xhQPMmwh5ALzW";
var encoded =
r"$2b$04$nQn78dV0hGHf5wUBe0zOFu8n07ZbWWOKoGasZKRspZxtt.vBRNMIy";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2b$04$cvXudZ5ugTg95W.rOjMITuM1jC0piCl3zF5cmGhzCibHZrNHkmckG", () {
var password = "59je8h5Gj71tg";
var encoded =
r"$2b$04$cvXudZ5ugTg95W.rOjMITuM1jC0piCl3zF5cmGhzCibHZrNHkmckG";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2b$04$YYjtiq4Uh88yUsExO0RNTuEJ.tZlsONac16A8OcLHleWFjVawfGvO", () {
var password = "wT4fHJa2N9WSW";
var encoded =
r"$2b$04$YYjtiq4Uh88yUsExO0RNTuEJ.tZlsONac16A8OcLHleWFjVawfGvO";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2b$04$WLTjgY/pZSyqX/fbMbJzf.qxCeTMQOzgL.CimRjMHtMxd/VGKojMu", () {
var password = "uSgFRnQdOgm4S";
var encoded =
r"$2b$04$WLTjgY/pZSyqX/fbMbJzf.qxCeTMQOzgL.CimRjMHtMxd/VGKojMu";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2b$04$2moPs/x/wnCfeQ5pCheMcuSJQ/KYjOZG780UjA/SiR.KsYWNrC7SG", () {
var password = "tEPtJZXur16Vg";
var encoded =
r"$2b$04$2moPs/x/wnCfeQ5pCheMcuSJQ/KYjOZG780UjA/SiR.KsYWNrC7SG";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2b$04$HrEYC/AQ2HS77G78cQDZQ.r44WGcruKw03KHlnp71yVQEwpsi3xl2", () {
var password = "vvho8C6nlVf9K";
var encoded =
r"$2b$04$HrEYC/AQ2HS77G78cQDZQ.r44WGcruKw03KHlnp71yVQEwpsi3xl2";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2b$04$vVYgSTfB8KVbmhbZE/k3R.ux9A0lJUM4CZwCkHI9fifke2.rTF7MG", () {
var password = "5auCCY9by0Ruf";
var encoded =
r"$2b$04$vVYgSTfB8KVbmhbZE/k3R.ux9A0lJUM4CZwCkHI9fifke2.rTF7MG";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2b$04$JfoNrR8.doieoI8..F.C1OQgwE3uTeuardy6lw0AjALUzOARoyf2m", () {
var password = "GtTkR6qn2QOZW";
var encoded =
r"$2b$04$JfoNrR8.doieoI8..F.C1OQgwE3uTeuardy6lw0AjALUzOARoyf2m";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2b$04$HP3I0PUs7KBEzMBNFw7o3O7f/uxaZU7aaDot1quHMgB2yrwBXsgyy", () {
var password = "zKo8vdFSnjX0f";
var encoded =
r"$2b$04$HP3I0PUs7KBEzMBNFw7o3O7f/uxaZU7aaDot1quHMgB2yrwBXsgyy";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2b$04$xnFVhJsTzsFBTeP3PpgbMeMREb6rdKV9faW54Sx.yg9plf4jY8qT6", () {
var password = "I9VfYlacJiwiK";
var encoded =
r"$2b$04$xnFVhJsTzsFBTeP3PpgbMeMREb6rdKV9faW54Sx.yg9plf4jY8qT6";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2b$04$WQp9.igoLqVr6Qk70mz6xuRxE0RttVXXdukpR9N54x17ecad34ZF6", () {
var password = "VFPO7YXnHQbQO";
var encoded =
r"$2b$04$WQp9.igoLqVr6Qk70mz6xuRxE0RttVXXdukpR9N54x17ecad34ZF6";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2b$04$xgZtlonpAHSU/njOCdKztOPuPFzCNVpB4LGicO4/OGgHv.uKHkwsS", () {
var password = "VDx5BdxfxstYk";
var encoded =
r"$2b$04$xgZtlonpAHSU/njOCdKztOPuPFzCNVpB4LGicO4/OGgHv.uKHkwsS";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2b$04$2Siw3Nv3Q/gTOIPetAyPr.GNj3aO0lb1E5E9UumYGKjP9BYqlNWJe", () {
var password = "dEe6XfVGrrfSH";
var encoded =
r"$2b$04$2Siw3Nv3Q/gTOIPetAyPr.GNj3aO0lb1E5E9UumYGKjP9BYqlNWJe";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2b$04$7/Qj7Kd8BcSahPO4khB8me4ssDJCW3r4OGYqPF87jxtrSyPj5cS5m", () {
var password = "cTT0EAFdwJiLn";
var encoded =
r"$2b$04$7/Qj7Kd8BcSahPO4khB8me4ssDJCW3r4OGYqPF87jxtrSyPj5cS5m";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2b$04$VvlCUKbTMjaxaYJ.k5juoecpG/7IzcH1AkmqKi.lIZMVIOLClWAk.", () {
var password = "J8eHUDuxBB520";
var encoded =
r"$2b$04$VvlCUKbTMjaxaYJ.k5juoecpG/7IzcH1AkmqKi.lIZMVIOLClWAk.";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2b$10$keO.ZZs22YtygVF6BLfhGOI/JjshJYPp8DZsUtym6mJV2Eha2Hdd.", () {
var password = [
125, 62, 179, 254, 241, 139, 160, 230, 40, 162, 76, 122, 113, 195, //
80, 127, 204, 200, 98, 123, 249, 20, 246, 246, 96, 129, 71, 53, 236,
29, 135, 16, 191, 167, 225, 125, 73, 55, 32, 150, 223, 99, 242, 191,
179, 86, 104, 223, 77, 136, 113, 247, 255, 27, 130, 126, 122, 19, 221,
233, 132, 0, 221, 52
];
var encoded =
r"$2b$10$keO.ZZs22YtygVF6BLfhGOI/JjshJYPp8DZsUtym6mJV2Eha2Hdd.";
var output = bcrypt(password, encoded);
expect(output, equals(encoded));
});
});
}

View file

@ -0,0 +1,24 @@
// Copyright (c) 2023, Sudipto Chandra
// All rights reserved. Check LICENSE file for details.
import 'package:hashlib/hashlib.dart';
import 'package:test/test.dart';
void main() {
group('bcrypt version 2y', () {
test(r"$2y$05$/OK.fbVrR/bpIqNJ5ianF.Sa7shbm4.OzKpvFnX1pQLmQW96oUlCq", () {
var password = "\xa3";
var encoded =
r"$2y$05$/OK.fbVrR/bpIqNJ5ianF.Sa7shbm4.OzKpvFnX1pQLmQW96oUlCq";
var output = bcrypt(password.codeUnits, encoded);
expect(output, equals(encoded));
});
test(r"$2y$05$/OK.fbVrR/bpIqNJ5ianF.CE5elHaaO4EbggVDjb8P19RukzXSM3e", () {
var password = "\xff\xff\xa3";
var encoded =
r"$2y$05$/OK.fbVrR/bpIqNJ5ianF.CE5elHaaO4EbggVDjb8P19RukzXSM3e";
var output = bcrypt(password.codeUnits, encoded);
expect(output, equals(encoded));
});
});
}

View file

@ -0,0 +1,221 @@
// Copyright (c) 2023, Sudipto Chandra
// All rights reserved. Check LICENSE file for details.
import 'dart:convert';
import 'package:hashlib/codecs.dart';
import 'package:hashlib/hashlib.dart';
import 'package:test/test.dart';
void main() {
group('bcrypt functionality', () {
test("name", () {
expect(Bcrypt(cost: 10).name, r'Bcrypt/2b');
expect(Bcrypt(cost: 10, version: BcryptVersion.$2a).name, r'Bcrypt/2a');
expect(Bcrypt(cost: 10, version: BcryptVersion.$2x).name, r'Bcrypt/2x');
expect(Bcrypt(cost: 10, version: BcryptVersion.$2y).name, r'Bcrypt/2y');
expect(Bcrypt(cost: 10, version: BcryptVersion.$2b).name, r'Bcrypt/2b');
});
// http://openwall.info/wiki/john/sample-hashes
test("bcrypt", () {
const password = r"password";
const salt = r"$2a$05$bvIG6Nmid91Mu9RcmmWZfO";
const encoded =
r"$2a$05$bvIG6Nmid91Mu9RcmmWZfO5HJIMCT8riNW0hEp8f6/FuA2/mHZFpe";
var output = bcrypt(utf8.encode(password), salt);
expect(output, equals(encoded));
});
test("bcryptVerify", () {
const password = r"password";
const encoded =
r"$2a$05$bvIG6Nmid91Mu9RcmmWZfO5HJIMCT8riNW0hEp8f6/FuA2/mHZFpe";
expect(bcryptVerify(encoded, password.codeUnits), true);
});
test("bcryptSalt", () {
final salt = bcryptSalt(nb: 5, version: BcryptVersion.$2a);
expect(salt.length, 29);
expect(salt, startsWith(r"$2a$05$"));
});
test("bcryptSalt with security", () {
final salt = bcryptSalt(security: BcryptSecurity.strong);
expect(salt.length, 29);
expect(salt, startsWith(r"$2b$15$"));
});
test("bcryptSalt with security overrides", () {
final salt = bcryptSalt(security: BcryptSecurity.strong, nb: 10);
expect(salt.length, 29);
expect(salt, startsWith(r"$2b$10$"));
});
test("bcryptDigest", () {
var password = "password".codeUnits;
var salt = fromBase64(
"bvIG6Nmid91Mu9RcmmWZfO",
codec: Base64Codec.bcrypt,
);
var result = fromBase64(
'5HJIMCT8riNW0hEp8f6/FuA2/mHZFpe',
codec: Base64Codec.bcrypt,
);
const encoded =
r"$2a$05$bvIG6Nmid91Mu9RcmmWZfO5HJIMCT8riNW0hEp8f6/FuA2/mHZFpe";
final output = bcryptDigest(
password,
nb: 5,
salt: salt,
version: BcryptVersion.$2a,
);
expect(output.bytes, equals(result));
expect(output.encoded(), equals(encoded));
expect(output.toString(), equals(encoded));
});
test("bcryptDigest with security", () {
var password = "password".codeUnits;
var salt = fromBase64(
"bvIG6Nmid91Mu9RcmmWZfO",
codec: Base64Codec.bcrypt,
);
var result = fromBase64(
'5HJIMCT8riNW0hEp8f6/FuA2/mHZFpe',
codec: Base64Codec.bcrypt,
);
final output = bcryptDigest(
password,
salt: salt,
version: BcryptVersion.$2a,
security: BcryptSecurity.little,
);
expect(output.bytes, equals(result));
});
test("Bcrypt instance with security", () {
var password = "password".codeUnits;
var salt = fromBase64(
"bvIG6Nmid91Mu9RcmmWZfO",
codec: Base64Codec.bcrypt,
);
var result = fromBase64(
'5HJIMCT8riNW0hEp8f6/FuA2/mHZFpe',
codec: Base64Codec.bcrypt,
);
final output = Bcrypt.fromSecurity(
BcryptSecurity.little,
salt: salt,
version: BcryptVersion.$2a,
).convert(password);
expect(output.bytes, equals(result));
});
test("The cost must be at least 0", () {
BcryptContext(cost: 0);
expect(() => BcryptContext(cost: -10), throwsArgumentError);
expect(() => BcryptContext(cost: -1), throwsArgumentError);
});
test("The cost must be at most 31", () {
BcryptContext(cost: 31);
expect(() => BcryptContext(cost: 32), throwsArgumentError);
expect(() => BcryptContext(cost: 100), throwsArgumentError);
});
test("The salt must be exactly 16-bytes", () {
BcryptContext(cost: 4, salt: List.filled(16, 0));
expect(
() => BcryptContext(cost: 4, salt: []),
throwsArgumentError,
);
expect(
() => BcryptContext(cost: 4, salt: List.filled(15, 0)),
throwsArgumentError,
);
expect(
() => BcryptContext(cost: 4, salt: List.filled(17, 0)),
throwsArgumentError,
);
});
test("Bcrypt from encoded", () {
Bcrypt.fromEncoded(fromCrypt(r"$2a$05$bvIG6Nmid91Mu9RcmmWZfO"));
});
test("Bcrypt from encoded with invalid version", () {
expect(
() => Bcrypt.fromEncoded(fromCrypt(r"$2c$05$bvIG6Nmid91Mu9RcmmWZfO")),
throwsA(
isA<FormatException>().having(
(e) => e.message,
'message',
'Invalid version',
),
),
);
});
test("Bcrypt from encoded with invalid cost", () {
expect(
() => Bcrypt.fromEncoded(fromCrypt(r"$2x$bvIG6Nmid91Mu9RcmmWZfO")),
throwsA(
isA<FormatException>().having(
(e) => e.message,
'message',
'Invalid cost',
),
),
);
expect(
() => Bcrypt.fromEncoded(fromCrypt(r"$2y$32$bvIG6Nmid91Mu9RcmmWZfO")),
throwsA(
isA<ArgumentError>().having(
(e) => e.message,
'message',
'The cost must be at most 31',
),
),
);
expect(
() => Bcrypt.fromEncoded(fromCrypt(r"$2y$-1$bvIG6Nmid91Mu9RcmmWZfO")),
throwsA(
isA<ArgumentError>().having(
(e) => e.message,
'message',
'The cost must be at least 0',
),
),
);
});
test("Bcrypt from encoded with invalid salt", () {
expect(
() => Bcrypt.fromEncoded(fromCrypt(r"$2b$05$bvIG6Nmid91Mu9RcmmWZf")),
throwsA(
isA<FormatException>().having(
(e) => e.message,
'message',
'Invalid hash',
),
),
);
expect(
() => Bcrypt.fromEncoded(fromCrypt(r"$2b$05$bvIG6Nmid91Mu9RcmmWZf0")),
throwsA(
isA<FormatException>().having(
(e) => e.message,
'message',
'Invalid length',
),
),
);
expect(
() => Bcrypt.fromEncoded(fromCrypt(
r"$2b$05$DCq7YPn5Rq63x1Lad4cll.TV4S6ytwfsfvkgY8jIucDrjc8deX1")),
throwsA(
isA<FormatException>().having(
(e) => e.message,
'message',
'Invalid hash',
),
),
);
Bcrypt.fromEncoded(fromCrypt(
r"$2a$06$DCq7YPn5Rq63x1Lad4cll.TV4S6ytwfsfvkgY8jIucDrjc8deX1s1",
));
});
});
}

View file

@ -0,0 +1,110 @@
// Copyright (c) 2023, Sudipto Chandra
// All rights reserved. Check LICENSE file for details.
import 'dart:convert';
import 'package:hashlib/hashlib.dart';
import 'package:test/test.dart';
void main() {
group('bcrypt big cost', () {
test(r"$2a$10$k1wbIrmNyFAPwPVPSVa/zecw2BCEnBwVS2GbrmgzxFUOqW9dk4TCW", () {
const password = r"";
const encoded =
r"$2a$10$k1wbIrmNyFAPwPVPSVa/zecw2BCEnBwVS2GbrmgzxFUOqW9dk4TCW";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2a$12$k42ZFHFWqBp3vWli.nIn8uYyIkbvYRvodzbfbK18SSsY.CsIQPlxO", () {
const password = r"";
const encoded =
r"$2a$12$k42ZFHFWqBp3vWli.nIn8uYyIkbvYRvodzbfbK18SSsY.CsIQPlxO";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2a$08$cfcvVd2aQ8CMvoMpP2EBfeodLEkkFJ9umNEfPD18.hUF62qqlC/V.", () {
const password = r"a";
const encoded =
r"$2a$08$cfcvVd2aQ8CMvoMpP2EBfeodLEkkFJ9umNEfPD18.hUF62qqlC/V.";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2a$10$k87L/MF28Q673VKh8/cPi.SUl7MU/rWuSiIDDFayrKk/1tBsSQu4u", () {
const password = r"a";
const encoded =
r"$2a$10$k87L/MF28Q673VKh8/cPi.SUl7MU/rWuSiIDDFayrKk/1tBsSQu4u";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2a$12$8NJH3LsPrANStV6XtBakCez0cKHXVxmvxIlcz785vxAIZrihHZpeS", () {
const password = r"a";
const encoded =
r"$2a$12$8NJH3LsPrANStV6XtBakCez0cKHXVxmvxIlcz785vxAIZrihHZpeS";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2a$08$Ro0CUfOqk6cXEKf3dyaM7OhSCvnwM9s4wIX9JeLapehKK5YdLxKcm", () {
const password = r"abc";
const encoded =
r"$2a$08$Ro0CUfOqk6cXEKf3dyaM7OhSCvnwM9s4wIX9JeLapehKK5YdLxKcm";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2a$10$WvvTPHKwdBJ3uk0Z37EMR.hLA2W6N9AEBhEgrAOljy2Ae5MtaSIUi", () {
const password = r"abc";
const encoded =
r"$2a$10$WvvTPHKwdBJ3uk0Z37EMR.hLA2W6N9AEBhEgrAOljy2Ae5MtaSIUi";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2a$12$EXRkfkdmXn2gzds2SSitu.MW9.gAVqa9eLS1//RYtYCmB1eLHg.9q", () {
const password = r"abc";
const encoded =
r"$2a$12$EXRkfkdmXn2gzds2SSitu.MW9.gAVqa9eLS1//RYtYCmB1eLHg.9q";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2a$08$aTsUwsyowQuzRrDqFflhgekJ8d9/7Z3GV3UcgvzQW3J5zMyrTvlz.", () {
const password = r"abcdefghijklmnopqrstuvwxyz";
const encoded =
r"$2a$08$aTsUwsyowQuzRrDqFflhgekJ8d9/7Z3GV3UcgvzQW3J5zMyrTvlz.";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2a$10$fVH8e28OQRj9tqiDXs1e1uxpsjN0c7II7YPKXua2NAKYvM6iQk7dq", () {
const password = r"abcdefghijklmnopqrstuvwxyz";
const encoded =
r"$2a$10$fVH8e28OQRj9tqiDXs1e1uxpsjN0c7II7YPKXua2NAKYvM6iQk7dq";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2a$12$D4G5f18o7aMMfwasBL7GpuQWuP3pkrZrOAnqP.bmezbMng.QwJ/pG", () {
const password = r"abcdefghijklmnopqrstuvwxyz";
const encoded =
r"$2a$12$D4G5f18o7aMMfwasBL7GpuQWuP3pkrZrOAnqP.bmezbMng.QwJ/pG";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2a$08$Eq2r4G/76Wv39MzSX262huzPz612MZiYHVUJe/OcOql2jo4.9UxTW", () {
const password = r"~!@#$%^&*() ~!@#$%^&*()PNBFRD";
const encoded =
r"$2a$08$Eq2r4G/76Wv39MzSX262huzPz612MZiYHVUJe/OcOql2jo4.9UxTW";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2a$10$LgfYWkbzEvQ4JakH7rOvHe0y8pHKF9OaFgwUZ2q7W2FFZmZzJYlfS", () {
const password = r"~!@#$%^&*() ~!@#$%^&*()PNBFRD";
const encoded =
r"$2a$10$LgfYWkbzEvQ4JakH7rOvHe0y8pHKF9OaFgwUZ2q7W2FFZmZzJYlfS";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2a$12$WApznUOJfkEGSmYRfnkrPOr466oFDCaj4b6HY3EXGvfxm43seyhgC", () {
const password = r"~!@#$%^&*() ~!@#$%^&*()PNBFRD";
const encoded =
r"$2a$12$WApznUOJfkEGSmYRfnkrPOr466oFDCaj4b6HY3EXGvfxm43seyhgC";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
}, skip: true);
}

View file

@ -1,643 +0,0 @@
// Copyright (c) 2023, Sudipto Chandra
// All rights reserved. Check LICENSE file for details.
import 'dart:convert';
import 'package:hashlib/codecs.dart';
import 'package:hashlib/hashlib.dart';
import 'package:test/test.dart';
void main() {
group('bcrypt test', () {
group('functionality test', () {
test("name", () {
expect(Bcrypt(cost: 10).name, r'Bcrypt/2b');
expect(Bcrypt(cost: 10, version: BcryptVersion.$2a).name, r'Bcrypt/2a');
expect(Bcrypt(cost: 10, version: BcryptVersion.$2x).name, r'Bcrypt/2x');
expect(Bcrypt(cost: 10, version: BcryptVersion.$2y).name, r'Bcrypt/2y');
expect(Bcrypt(cost: 10, version: BcryptVersion.$2b).name, r'Bcrypt/2b');
});
// http://openwall.info/wiki/john/sample-hashes
test("bcrypt", () {
const password = r"password";
const salt = r"$2a$05$bvIG6Nmid91Mu9RcmmWZfO";
const encoded =
r"$2a$05$bvIG6Nmid91Mu9RcmmWZfO5HJIMCT8riNW0hEp8f6/FuA2/mHZFpe";
var output = bcrypt(utf8.encode(password), salt);
expect(output, equals(encoded));
});
test("bcryptVerify", () {
const password = r"password";
const encoded =
r"$2a$05$bvIG6Nmid91Mu9RcmmWZfO5HJIMCT8riNW0hEp8f6/FuA2/mHZFpe";
expect(bcryptVerify(encoded, password.codeUnits), true);
});
test("bcryptSalt", () {
final salt = bcryptSalt(nb: 5, version: BcryptVersion.$2a);
expect(salt.length, 29);
expect(salt, startsWith(r"$2a$05$"));
});
test("bcryptSalt with security", () {
final salt = bcryptSalt(security: BcryptSecurity.strong);
expect(salt.length, 29);
expect(salt, startsWith(r"$2b$15$"));
});
test("bcryptSalt with security overrides", () {
final salt = bcryptSalt(security: BcryptSecurity.strong, nb: 10);
expect(salt.length, 29);
expect(salt, startsWith(r"$2b$10$"));
});
test("bcryptDigest", () {
var password = "password".codeUnits;
var salt = fromBase64(
"bvIG6Nmid91Mu9RcmmWZfO",
codec: Base64Codec.bcrypt,
);
var result = fromBase64(
'5HJIMCT8riNW0hEp8f6/FuA2/mHZFpe',
codec: Base64Codec.bcrypt,
);
const encoded =
r"$2a$05$bvIG6Nmid91Mu9RcmmWZfO5HJIMCT8riNW0hEp8f6/FuA2/mHZFpe";
final output = bcryptDigest(
password,
nb: 5,
salt: salt,
version: BcryptVersion.$2a,
);
expect(output.bytes, equals(result));
expect(output.encoded(), equals(encoded));
expect(output.toString(), equals(encoded));
});
test("bcryptDigest with security", () {
var password = "password".codeUnits;
var salt = fromBase64(
"bvIG6Nmid91Mu9RcmmWZfO",
codec: Base64Codec.bcrypt,
);
var result = fromBase64(
'5HJIMCT8riNW0hEp8f6/FuA2/mHZFpe',
codec: Base64Codec.bcrypt,
);
final output = bcryptDigest(
password,
salt: salt,
version: BcryptVersion.$2a,
security: BcryptSecurity.little,
);
expect(output.bytes, equals(result));
});
test("Bcrypt instance with security", () {
var password = "password".codeUnits;
var salt = fromBase64(
"bvIG6Nmid91Mu9RcmmWZfO",
codec: Base64Codec.bcrypt,
);
var result = fromBase64(
'5HJIMCT8riNW0hEp8f6/FuA2/mHZFpe',
codec: Base64Codec.bcrypt,
);
final output = Bcrypt.fromSecurity(
BcryptSecurity.little,
salt: salt,
version: BcryptVersion.$2a,
).convert(password);
expect(output.bytes, equals(result));
});
test("The cost must be at least 0", () {
BcryptContext(cost: 0);
expect(() => BcryptContext(cost: -10), throwsArgumentError);
expect(() => BcryptContext(cost: -1), throwsArgumentError);
});
test("The cost must be at most 31", () {
BcryptContext(cost: 31);
expect(() => BcryptContext(cost: 32), throwsArgumentError);
expect(() => BcryptContext(cost: 100), throwsArgumentError);
});
test("The salt must be exactly 16-bytes", () {
BcryptContext(cost: 4, salt: List.filled(16, 0));
expect(
() => BcryptContext(cost: 4, salt: []),
throwsArgumentError,
);
expect(
() => BcryptContext(cost: 4, salt: List.filled(15, 0)),
throwsArgumentError,
);
expect(
() => BcryptContext(cost: 4, salt: List.filled(17, 0)),
throwsArgumentError,
);
});
test("Bcrypt from encoded", () {
Bcrypt.fromEncoded(fromCrypt(r"$2a$05$bvIG6Nmid91Mu9RcmmWZfO"));
});
test("Bcrypt from encoded with invalid version", () {
expect(
() => Bcrypt.fromEncoded(fromCrypt(r"$2c$05$bvIG6Nmid91Mu9RcmmWZfO")),
throwsA(
isA<FormatException>().having(
(e) => e.message,
'message',
'Invalid version',
),
),
);
});
test("Bcrypt from encoded with invalid cost", () {
expect(
() => Bcrypt.fromEncoded(fromCrypt(r"$2x$bvIG6Nmid91Mu9RcmmWZfO")),
throwsA(
isA<FormatException>().having(
(e) => e.message,
'message',
'Invalid cost',
),
),
);
expect(
() => Bcrypt.fromEncoded(fromCrypt(r"$2y$32$bvIG6Nmid91Mu9RcmmWZfO")),
throwsA(
isA<ArgumentError>().having(
(e) => e.message,
'message',
'The cost must be at most 31',
),
),
);
expect(
() => Bcrypt.fromEncoded(fromCrypt(r"$2y$-1$bvIG6Nmid91Mu9RcmmWZfO")),
throwsA(
isA<ArgumentError>().having(
(e) => e.message,
'message',
'The cost must be at least 0',
),
),
);
});
test("Bcrypt from encoded with invalid salt", () {
expect(
() => Bcrypt.fromEncoded(fromCrypt(r"$2b$05$bvIG6Nmid91Mu9RcmmWZf")),
throwsA(
isA<FormatException>().having(
(e) => e.message,
'message',
'Invalid hash',
),
),
);
expect(
() => Bcrypt.fromEncoded(fromCrypt(r"$2b$05$bvIG6Nmid91Mu9RcmmWZf0")),
throwsA(
isA<FormatException>().having(
(e) => e.message,
'message',
'Invalid length',
),
),
);
expect(
() => Bcrypt.fromEncoded(fromCrypt(
r"$2b$05$DCq7YPn5Rq63x1Lad4cll.TV4S6ytwfsfvkgY8jIucDrjc8deX1")),
throwsA(
isA<FormatException>().having(
(e) => e.message,
'message',
'Invalid hash',
),
),
);
Bcrypt.fromEncoded(fromCrypt(
r"$2a$06$DCq7YPn5Rq63x1Lad4cll.TV4S6ytwfsfvkgY8jIucDrjc8deX1s1",
));
});
});
group('version 2a', () {
// http://cvsweb.openwall.com/cgi/cvsweb.cgi/Owl/packages/glibc/crypt_blowfish/wrapper.c?rev=HEAD
test(r"$2a$06$DCq7YPn5Rq63x1Lad4cll.TV4S6ytwfsfvkgY8jIucDrjc8deX1s.", () {
const password = r"";
const encoded =
r"$2a$06$DCq7YPn5Rq63x1Lad4cll.TV4S6ytwfsfvkgY8jIucDrjc8deX1s.";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
// https://stackoverflow.com/a/12761326/774398
test(r"$2a$10$.TtQJ4Jr6isd4Hp.mVfZeuh6Gws4rOQ/vdBczhDx.19NFK0Y84Dle", () {
const password = r"ππππππππ";
const encoded =
r"$2a$10$.TtQJ4Jr6isd4Hp.mVfZeuh6Gws4rOQ/vdBczhDx.19NFK0Y84Dle";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
// https://bitbucket.org/vadim/bcrypt.net/src/464c41416dc9/BCrypt.Net.Test/TestBCrypt.cs?fileviewer=file-view-default
test(r"$2a$08$HqWuK6/Ng6sg9gQzbLrgb.Tl.ZHfXLhvt/SgVyWhQqgqcZ7ZuUtye", () {
const password = r"";
const encoded =
r"$2a$08$HqWuK6/Ng6sg9gQzbLrgb.Tl.ZHfXLhvt/SgVyWhQqgqcZ7ZuUtye";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2a$06$m0CrhHm10qJ3lXRY.5zDGO3rS2KdeeWLuGmsfGlMfOxih58VYVfxe", () {
const password = r"a";
const encoded =
r"$2a$06$m0CrhHm10qJ3lXRY.5zDGO3rS2KdeeWLuGmsfGlMfOxih58VYVfxe";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2a$06$If6bvum7DFjUnE9p2uDeDu0YHzrHM6tf.iqN8.yx.jNN1ILEf7h0i", () {
const password = r"abc";
const encoded =
r"$2a$06$If6bvum7DFjUnE9p2uDeDu0YHzrHM6tf.iqN8.yx.jNN1ILEf7h0i";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2a$06$.rCVZVOThsIa97pEDOxvGuRRgzG64bvtJ0938xuqzv18d3ZpQhstC", () {
const password = r"abcdefghijklmnopqrstuvwxyz";
const encoded =
r"$2a$06$.rCVZVOThsIa97pEDOxvGuRRgzG64bvtJ0938xuqzv18d3ZpQhstC";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2a$06$fPIsBO8qRqkjj273rfaOI.HtSV9jLDpTbZn782DC6/t7qT67P6FfO", () {
const password = r"~!@#$%^&*() ~!@#$%^&*()PNBFRD";
const encoded =
r"$2a$06$fPIsBO8qRqkjj273rfaOI.HtSV9jLDpTbZn782DC6/t7qT67P6FfO";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
// https://github.com/pyca/bcrypt/blob/main/tests/test_bcrypt.py
test(r"$2a$05$CCCCCCCCCCCCCCCCCCCCC.E5YPO9kmyuRGyh0XouQYb4YMJKvyOeW", () {
var password = "U*U";
var encoded =
r"$2a$05$CCCCCCCCCCCCCCCCCCCCC.E5YPO9kmyuRGyh0XouQYb4YMJKvyOeW";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2a$05$CCCCCCCCCCCCCCCCCCCCC.VGOzA784oUp/Z0DY336zx7pLYAy0lwK", () {
var password = "U*U*";
var encoded =
r"$2a$05$CCCCCCCCCCCCCCCCCCCCC.VGOzA784oUp/Z0DY336zx7pLYAy0lwK";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2a$05$XXXXXXXXXXXXXXXXXXXXXOAcXxm9kjPGEMsLznoKqmqw7tc8WCx4a", () {
var password = "U*U*U";
var encoded =
r"$2a$05$XXXXXXXXXXXXXXXXXXXXXOAcXxm9kjPGEMsLznoKqmqw7tc8WCx4a";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2a$05$abcdefghijklmnopqrstuu5s2v8.iXieOjg/.AySBTTZIIVFJeBui", () {
var password = "0123456789abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
"chars after 72 are ignored";
var encoded =
r"$2a$05$abcdefghijklmnopqrstuu5s2v8.iXieOjg/.AySBTTZIIVFJeBui";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2a$05$/OK.fbVrR/bpIqNJ5ianF.swQOIzjOiJ9GHEPuhEkvqrUyvWhEMx6", () {
var password = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"chars after 72 are ignored as usual";
var encoded =
r"$2a$05$/OK.fbVrR/bpIqNJ5ianF.swQOIzjOiJ9GHEPuhEkvqrUyvWhEMx6";
var output = bcrypt(password.codeUnits, encoded);
expect(output, equals(encoded));
});
test(r"$2a$05$/OK.fbVrR/bpIqNJ5ianF.Sa7shbm4.OzKpvFnX1pQLmQW96oUlCq", () {
var password = "\xa3";
var encoded =
r"$2a$05$/OK.fbVrR/bpIqNJ5ianF.Sa7shbm4.OzKpvFnX1pQLmQW96oUlCq";
var output = bcrypt(password.codeUnits, encoded);
expect(output, equals(encoded));
});
test(r"$2a$04$tecY.9ylRInW/rAAzXCXPOOlyYeCNzmNTzPDNSIFztFMKbvs/s5XG", () {
var password =
"g7\r\x01\xf3\xd4\xd0\xa9JB^\x18\x007P\xb2N\xc7\x1c\xee\x87&\x83C"
"\x8b\xe8\x18\xc5>\x86\x14/\xd6\xcc\x1cJ\xde\xd7ix\xeb\xdeO\xef"
"\xe1i\xac\xcb\x03\x96v1' \xd6@.m\xa5!\xa0\xef\xc0(";
var encoded =
r"$2a$04$tecY.9ylRInW/rAAzXCXPOOlyYeCNzmNTzPDNSIFztFMKbvs/s5XG";
var output = bcrypt(password.codeUnits, encoded);
expect(output, equals(encoded));
});
});
group('version 2y', () {
test(r"$2y$05$/OK.fbVrR/bpIqNJ5ianF.Sa7shbm4.OzKpvFnX1pQLmQW96oUlCq", () {
var password = "\xa3";
var encoded =
r"$2y$05$/OK.fbVrR/bpIqNJ5ianF.Sa7shbm4.OzKpvFnX1pQLmQW96oUlCq";
var output = bcrypt(password.codeUnits, encoded);
expect(output, equals(encoded));
});
test(r"$2y$05$/OK.fbVrR/bpIqNJ5ianF.CE5elHaaO4EbggVDjb8P19RukzXSM3e", () {
var password = "\xff\xff\xa3";
var encoded =
r"$2y$05$/OK.fbVrR/bpIqNJ5ianF.CE5elHaaO4EbggVDjb8P19RukzXSM3e";
var output = bcrypt(password.codeUnits, encoded);
expect(output, equals(encoded));
});
});
// https://github.com/pyca/bcrypt/blob/main/tests/test_bcrypt.py
group('version 2b', () {
test(r"$2b$04$cVWp4XaNU8a4v1uMRum2SO026BWLIoQMD/TXg5uZV.0P.uO8m3YEm", () {
var password = "Kk4DQuMMfZL9o";
var encoded =
r"$2b$04$cVWp4XaNU8a4v1uMRum2SO026BWLIoQMD/TXg5uZV.0P.uO8m3YEm";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2b$04$pQ7gRO7e6wx/936oXhNjrOUNOHL1D0h1N2IDbJZYs.1ppzSof6SPy", () {
var password = "9IeRXmnGxMYbs";
var encoded =
r"$2b$04$pQ7gRO7e6wx/936oXhNjrOUNOHL1D0h1N2IDbJZYs.1ppzSof6SPy";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2b$04$SQe9knOzepOVKoYXo9xTteNYr6MBwVz4tpriJVe3PNgYufGIsgKcW", () {
var password = "xVQVbwa1S0M8r";
var encoded =
r"$2b$04$SQe9knOzepOVKoYXo9xTteNYr6MBwVz4tpriJVe3PNgYufGIsgKcW";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2b$04$eH8zX.q5Q.j2hO1NkVYJQOM6KxntS/ow3.YzVmFrE4t//CoF4fvne", () {
var password = "Zfgr26LWd22Za";
var encoded =
r"$2b$04$eH8zX.q5Q.j2hO1NkVYJQOM6KxntS/ow3.YzVmFrE4t//CoF4fvne";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2b$04$ahiTdwRXpUG2JLRcIznxc.s1.ydaPGD372bsGs8NqyYjLY1inG5n2", () {
var password = "Tg4daC27epFBE";
var encoded =
r"$2b$04$ahiTdwRXpUG2JLRcIznxc.s1.ydaPGD372bsGs8NqyYjLY1inG5n2";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2b$04$nQn78dV0hGHf5wUBe0zOFu8n07ZbWWOKoGasZKRspZxtt.vBRNMIy", () {
var password = "xhQPMmwh5ALzW";
var encoded =
r"$2b$04$nQn78dV0hGHf5wUBe0zOFu8n07ZbWWOKoGasZKRspZxtt.vBRNMIy";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2b$04$cvXudZ5ugTg95W.rOjMITuM1jC0piCl3zF5cmGhzCibHZrNHkmckG", () {
var password = "59je8h5Gj71tg";
var encoded =
r"$2b$04$cvXudZ5ugTg95W.rOjMITuM1jC0piCl3zF5cmGhzCibHZrNHkmckG";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2b$04$YYjtiq4Uh88yUsExO0RNTuEJ.tZlsONac16A8OcLHleWFjVawfGvO", () {
var password = "wT4fHJa2N9WSW";
var encoded =
r"$2b$04$YYjtiq4Uh88yUsExO0RNTuEJ.tZlsONac16A8OcLHleWFjVawfGvO";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2b$04$WLTjgY/pZSyqX/fbMbJzf.qxCeTMQOzgL.CimRjMHtMxd/VGKojMu", () {
var password = "uSgFRnQdOgm4S";
var encoded =
r"$2b$04$WLTjgY/pZSyqX/fbMbJzf.qxCeTMQOzgL.CimRjMHtMxd/VGKojMu";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2b$04$2moPs/x/wnCfeQ5pCheMcuSJQ/KYjOZG780UjA/SiR.KsYWNrC7SG", () {
var password = "tEPtJZXur16Vg";
var encoded =
r"$2b$04$2moPs/x/wnCfeQ5pCheMcuSJQ/KYjOZG780UjA/SiR.KsYWNrC7SG";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2b$04$HrEYC/AQ2HS77G78cQDZQ.r44WGcruKw03KHlnp71yVQEwpsi3xl2", () {
var password = "vvho8C6nlVf9K";
var encoded =
r"$2b$04$HrEYC/AQ2HS77G78cQDZQ.r44WGcruKw03KHlnp71yVQEwpsi3xl2";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2b$04$vVYgSTfB8KVbmhbZE/k3R.ux9A0lJUM4CZwCkHI9fifke2.rTF7MG", () {
var password = "5auCCY9by0Ruf";
var encoded =
r"$2b$04$vVYgSTfB8KVbmhbZE/k3R.ux9A0lJUM4CZwCkHI9fifke2.rTF7MG";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2b$04$JfoNrR8.doieoI8..F.C1OQgwE3uTeuardy6lw0AjALUzOARoyf2m", () {
var password = "GtTkR6qn2QOZW";
var encoded =
r"$2b$04$JfoNrR8.doieoI8..F.C1OQgwE3uTeuardy6lw0AjALUzOARoyf2m";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2b$04$HP3I0PUs7KBEzMBNFw7o3O7f/uxaZU7aaDot1quHMgB2yrwBXsgyy", () {
var password = "zKo8vdFSnjX0f";
var encoded =
r"$2b$04$HP3I0PUs7KBEzMBNFw7o3O7f/uxaZU7aaDot1quHMgB2yrwBXsgyy";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2b$04$xnFVhJsTzsFBTeP3PpgbMeMREb6rdKV9faW54Sx.yg9plf4jY8qT6", () {
var password = "I9VfYlacJiwiK";
var encoded =
r"$2b$04$xnFVhJsTzsFBTeP3PpgbMeMREb6rdKV9faW54Sx.yg9plf4jY8qT6";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2b$04$WQp9.igoLqVr6Qk70mz6xuRxE0RttVXXdukpR9N54x17ecad34ZF6", () {
var password = "VFPO7YXnHQbQO";
var encoded =
r"$2b$04$WQp9.igoLqVr6Qk70mz6xuRxE0RttVXXdukpR9N54x17ecad34ZF6";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2b$04$xgZtlonpAHSU/njOCdKztOPuPFzCNVpB4LGicO4/OGgHv.uKHkwsS", () {
var password = "VDx5BdxfxstYk";
var encoded =
r"$2b$04$xgZtlonpAHSU/njOCdKztOPuPFzCNVpB4LGicO4/OGgHv.uKHkwsS";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2b$04$2Siw3Nv3Q/gTOIPetAyPr.GNj3aO0lb1E5E9UumYGKjP9BYqlNWJe", () {
var password = "dEe6XfVGrrfSH";
var encoded =
r"$2b$04$2Siw3Nv3Q/gTOIPetAyPr.GNj3aO0lb1E5E9UumYGKjP9BYqlNWJe";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2b$04$7/Qj7Kd8BcSahPO4khB8me4ssDJCW3r4OGYqPF87jxtrSyPj5cS5m", () {
var password = "cTT0EAFdwJiLn";
var encoded =
r"$2b$04$7/Qj7Kd8BcSahPO4khB8me4ssDJCW3r4OGYqPF87jxtrSyPj5cS5m";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2b$04$VvlCUKbTMjaxaYJ.k5juoecpG/7IzcH1AkmqKi.lIZMVIOLClWAk.", () {
var password = "J8eHUDuxBB520";
var encoded =
r"$2b$04$VvlCUKbTMjaxaYJ.k5juoecpG/7IzcH1AkmqKi.lIZMVIOLClWAk.";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2b$10$keO.ZZs22YtygVF6BLfhGOI/JjshJYPp8DZsUtym6mJV2Eha2Hdd.", () {
var password = [
125, 62, 179, 254, 241, 139, 160, 230, 40, 162, 76, 122, 113, 195, //
80, 127, 204, 200, 98, 123, 249, 20, 246, 246, 96, 129, 71, 53, 236,
29, 135, 16, 191, 167, 225, 125, 73, 55, 32, 150, 223, 99, 242, 191,
179, 86, 104, 223, 77, 136, 113, 247, 255, 27, 130, 126, 122, 19, 221,
233, 132, 0, 221, 52
];
var encoded =
r"$2b$10$keO.ZZs22YtygVF6BLfhGOI/JjshJYPp8DZsUtym6mJV2Eha2Hdd.";
var output = bcrypt(password, encoded);
expect(output, equals(encoded));
});
});
group('big cost', () {
test(r"$2a$10$k1wbIrmNyFAPwPVPSVa/zecw2BCEnBwVS2GbrmgzxFUOqW9dk4TCW", () {
const password = r"";
const encoded =
r"$2a$10$k1wbIrmNyFAPwPVPSVa/zecw2BCEnBwVS2GbrmgzxFUOqW9dk4TCW";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2a$12$k42ZFHFWqBp3vWli.nIn8uYyIkbvYRvodzbfbK18SSsY.CsIQPlxO", () {
const password = r"";
const encoded =
r"$2a$12$k42ZFHFWqBp3vWli.nIn8uYyIkbvYRvodzbfbK18SSsY.CsIQPlxO";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2a$08$cfcvVd2aQ8CMvoMpP2EBfeodLEkkFJ9umNEfPD18.hUF62qqlC/V.", () {
const password = r"a";
const encoded =
r"$2a$08$cfcvVd2aQ8CMvoMpP2EBfeodLEkkFJ9umNEfPD18.hUF62qqlC/V.";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2a$10$k87L/MF28Q673VKh8/cPi.SUl7MU/rWuSiIDDFayrKk/1tBsSQu4u", () {
const password = r"a";
const encoded =
r"$2a$10$k87L/MF28Q673VKh8/cPi.SUl7MU/rWuSiIDDFayrKk/1tBsSQu4u";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2a$12$8NJH3LsPrANStV6XtBakCez0cKHXVxmvxIlcz785vxAIZrihHZpeS", () {
const password = r"a";
const encoded =
r"$2a$12$8NJH3LsPrANStV6XtBakCez0cKHXVxmvxIlcz785vxAIZrihHZpeS";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2a$08$Ro0CUfOqk6cXEKf3dyaM7OhSCvnwM9s4wIX9JeLapehKK5YdLxKcm", () {
const password = r"abc";
const encoded =
r"$2a$08$Ro0CUfOqk6cXEKf3dyaM7OhSCvnwM9s4wIX9JeLapehKK5YdLxKcm";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2a$10$WvvTPHKwdBJ3uk0Z37EMR.hLA2W6N9AEBhEgrAOljy2Ae5MtaSIUi", () {
const password = r"abc";
const encoded =
r"$2a$10$WvvTPHKwdBJ3uk0Z37EMR.hLA2W6N9AEBhEgrAOljy2Ae5MtaSIUi";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2a$12$EXRkfkdmXn2gzds2SSitu.MW9.gAVqa9eLS1//RYtYCmB1eLHg.9q", () {
const password = r"abc";
const encoded =
r"$2a$12$EXRkfkdmXn2gzds2SSitu.MW9.gAVqa9eLS1//RYtYCmB1eLHg.9q";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2a$08$aTsUwsyowQuzRrDqFflhgekJ8d9/7Z3GV3UcgvzQW3J5zMyrTvlz.", () {
const password = r"abcdefghijklmnopqrstuvwxyz";
const encoded =
r"$2a$08$aTsUwsyowQuzRrDqFflhgekJ8d9/7Z3GV3UcgvzQW3J5zMyrTvlz.";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2a$10$fVH8e28OQRj9tqiDXs1e1uxpsjN0c7II7YPKXua2NAKYvM6iQk7dq", () {
const password = r"abcdefghijklmnopqrstuvwxyz";
const encoded =
r"$2a$10$fVH8e28OQRj9tqiDXs1e1uxpsjN0c7II7YPKXua2NAKYvM6iQk7dq";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2a$12$D4G5f18o7aMMfwasBL7GpuQWuP3pkrZrOAnqP.bmezbMng.QwJ/pG", () {
const password = r"abcdefghijklmnopqrstuvwxyz";
const encoded =
r"$2a$12$D4G5f18o7aMMfwasBL7GpuQWuP3pkrZrOAnqP.bmezbMng.QwJ/pG";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2a$08$Eq2r4G/76Wv39MzSX262huzPz612MZiYHVUJe/OcOql2jo4.9UxTW", () {
const password = r"~!@#$%^&*() ~!@#$%^&*()PNBFRD";
const encoded =
r"$2a$08$Eq2r4G/76Wv39MzSX262huzPz612MZiYHVUJe/OcOql2jo4.9UxTW";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2a$10$LgfYWkbzEvQ4JakH7rOvHe0y8pHKF9OaFgwUZ2q7W2FFZmZzJYlfS", () {
const password = r"~!@#$%^&*() ~!@#$%^&*()PNBFRD";
const encoded =
r"$2a$10$LgfYWkbzEvQ4JakH7rOvHe0y8pHKF9OaFgwUZ2q7W2FFZmZzJYlfS";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
test(r"$2a$12$WApznUOJfkEGSmYRfnkrPOr466oFDCaj4b6HY3EXGvfxm43seyhgC", () {
const password = r"~!@#$%^&*() ~!@#$%^&*()PNBFRD";
const encoded =
r"$2a$12$WApznUOJfkEGSmYRfnkrPOr466oFDCaj4b6HY3EXGvfxm43seyhgC";
var output = bcrypt(utf8.encode(password), encoded);
expect(output, equals(encoded));
});
}, skip: true);
});
}

View file

@ -0,0 +1,109 @@
// Copyright (c) 2023, Sudipto Chandra
// All rights reserved. Check LICENSE file for details.
// ignore_for_file: library_annotations
@Tags(['vm-only'])
import 'package:hashlib/codecs.dart';
import 'package:hashlib/hashlib.dart';
import 'package:hashlib/random.dart';
import 'package:pointycastle/digests/blake2b.dart' as pc_blake2b;
import 'package:test/test.dart';
void main() {
group('blake2b512 comparison', () {
test('with pointycastle', () {
for (int i = 0; i < 100; ++i) {
final data = randomBytes(i);
final out1 = blake2b512.convert(data).hex();
final out2 = toHex(
pc_blake2b.Blake2bDigest(digestSize: 64).process(data),
);
expect(out1, equals(out2), reason: 'size: $i');
}
});
test('with pointycastle with key', () {
final key = randomBytes(16);
for (int i = 0; i < 100; ++i) {
final data = randomBytes(i);
final out1 = blake2b512.mac.by(key).convert(data).hex();
final out2 = toHex(
pc_blake2b.Blake2bDigest(digestSize: 64, key: key).process(data),
);
expect(out1, equals(out2), reason: 'size: $i');
}
});
test('with pointycastle with salt', () {
final salt = randomBytes(16);
for (int i = 0; i < 100; ++i) {
final data = randomBytes(i);
final out1 = Blake2b(64, salt: salt).convert(data).hex();
final out2 = toHex(
pc_blake2b.Blake2bDigest(digestSize: 64, salt: salt).process(data),
);
expect(out1, equals(out2), reason: 'size: $i');
}
});
test('with pointycastle with personalization', () {
final personalization = randomBytes(16);
for (int i = 0; i < 100; ++i) {
final data = randomBytes(i);
final out1 = Blake2b(
64,
aad: personalization,
).convert(data).hex();
final out2 = toHex(
pc_blake2b.Blake2bDigest(
digestSize: 64,
personalization: personalization,
).process(data),
);
expect(out1, equals(out2), reason: 'size: $i');
}
});
test('with pointycastle with salt and personalization', () {
final salt = randomBytes(16);
final personalization = randomBytes(16);
for (int i = 0; i < 100; ++i) {
final data = randomBytes(i);
final out1 = Blake2b(
64,
salt: salt,
aad: personalization,
).convert(data).hex();
final out2 = toHex(
pc_blake2b.Blake2bDigest(
digestSize: 64,
salt: salt,
personalization: personalization,
).process(data),
);
expect(out1, equals(out2), reason: 'size: $i');
}
});
test('with pointycastle with key, salt and personalization', () {
final key = randomBytes(16);
final salt = randomBytes(16);
final aad = randomBytes(16);
for (int i = 0; i < 100; ++i) {
final data = randomBytes(i);
final out1 = Blake2b(64).mac.by(key, salt: salt, aad: aad).hex(data);
final out2 = toHex(
pc_blake2b.Blake2bDigest(
digestSize: 64,
key: key,
salt: salt,
personalization: aad,
).process(data),
);
expect(out1, equals(out2), reason: 'size: $i');
}
});
});
}

View file

@ -0,0 +1,55 @@
// Copyright (c) 2023, Sudipto Chandra
// All rights reserved. Check LICENSE file for details.
// ignore_for_file: library_annotations
@Tags(['vm-only'])
import 'package:crypto/crypto.dart' as crypto;
import 'package:hashlib/codecs.dart';
import 'package:hashlib/hashlib.dart';
import 'package:hashlib/random.dart';
import 'package:test/test.dart';
void main() {
group('HMAC comparison', () {
test('with crypto for MD5', () {
var key = "key";
var msg = "The quick brown fox jumps over the lazy dog";
var expected = "80070713463e7749b90c2dc24911e275";
var actual = toHex(
md5.hmac.byString(key).convert(msg.codeUnits).bytes,
);
var actual2 = toHex(
crypto.Hmac(crypto.md5, key.codeUnits).convert(msg.codeUnits).bytes,
);
expect(actual2, expected, reason: "Key: $key | Message: $msg");
expect(actual, expected, reason: "Key: $key | Message: $msg");
});
test('with crypto', () {
for (int i = 0; i < 100; ++i) {
final data = randomBytes(i);
final key = randomBytes(i & 0x7F);
expect(
toHex(sha1.hmac.by(key).convert(data).bytes),
toHex(crypto.Hmac(crypto.sha1, key).convert(data).bytes),
reason: 'Key: "${String.fromCharCodes(key)}" [${key.length}]\n'
'Message: "${String.fromCharCodes(data)}" [${data.length}]',
);
}
});
test('run in parallel', () async {
await Future.wait(List.generate(10, (i) => i).map((i) async {
final data = randomBytes(i);
final key = randomBytes(i & 0x7F);
expect(
toHex(sha384.hmac.by(key).convert(data).bytes),
toHex(crypto.Hmac(crypto.sha384, key).convert(data).bytes),
reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]',
);
}));
});
});
}

View file

@ -0,0 +1,45 @@
// Copyright (c) 2023, Sudipto Chandra
// All rights reserved. Check LICENSE file for details.
// ignore_for_file: library_annotations
@Tags(['vm-only'])
import 'dart:typed_data';
import 'package:hashlib/codecs.dart';
import 'package:hashlib/hashlib.dart';
import 'package:hashlib/random.dart';
import 'package:pointycastle/digests/keccak.dart' as pc_keccak;
import 'package:pointycastle/digests/sha3.dart' as pc_sha3;
import 'package:test/test.dart';
void main() {
group('Keccak comparison', () {
test('with keccak256', () {
for (int i = 0; i < 100; ++i) {
final data = randomBytes(i);
var pc = pc_keccak.KeccakDigest(256);
var other = pc.process(Uint8List.fromList(data));
expect(
keccak256.convert(data).hex(),
toHex(other),
reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]',
);
}
});
test('with sha3', () {
for (int i = 0; i < 100; ++i) {
final data = randomBytes(i);
var pc = pc_sha3.SHA3Digest(256);
var other = pc.process(Uint8List.fromList(data));
expect(
sha3_256.convert(data).hex(),
toHex(other),
reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]',
);
}
});
});
}

View file

@ -0,0 +1,36 @@
// Copyright (c) 2023, Sudipto Chandra
// All rights reserved. Check LICENSE file for details.
// ignore_for_file: library_annotations
@Tags(['vm-only'])
import 'dart:io';
import 'package:hashlib/codecs.dart';
import 'package:hashlib/hashlib.dart';
import 'package:hashlib/random.dart';
import 'package:pointycastle/digests/md4.dart' as pc_md4;
import 'package:test/test.dart';
void main() {
group('MD4 comparison', () {
test('with pointy-castle', () {
for (int i = 0; i < 100; ++i) {
final data = randomBytes(i);
expect(
toHex(md4.convert(data).bytes),
toHex(pc_md4.MD4Digest().process(data)),
reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]',
);
}
});
test('for a file sync', () {
var file = File('LICENSE');
var hash = pc_md4.MD4Digest().process(file.readAsBytesSync());
var hash2 = md4.fileSync(file);
expect(hash2.hex(), toHex(hash));
}, tags: 'vm-only');
});
}

View file

@ -0,0 +1,54 @@
// Copyright (c) 2023, Sudipto Chandra
// All rights reserved. Check LICENSE file for details.
// ignore_for_file: library_annotations
@Tags(['vm-only'])
import 'dart:io';
import 'package:crypto/crypto.dart' as crypto;
import 'package:hashlib/codecs.dart';
import 'package:hashlib/hashlib.dart';
import 'package:hashlib/random.dart';
import 'package:test/test.dart';
void main() {
group('MD5 comparison', () {
test('for a file async', () async {
var file = File('LICENSE');
var hash = await crypto.md5.bind(file.openRead()).first;
var hash2 = await md5.file(file);
expect(hash2.hex(), toHex(hash.bytes));
}, tags: 'vm-only');
test('for a file sync', () async {
var file = File('LICENSE');
var hash = await crypto.md5.bind(file.openRead()).first;
var hash2 = md5.fileSync(file);
expect(hash2.hex(), toHex(hash.bytes));
}, tags: 'vm-only');
test('with crypto', () {
for (int i = 0; i < 100; ++i) {
final data = randomBytes(i);
expect(
toHex(md5.convert(data).bytes),
toHex(crypto.md5.convert(data).bytes),
reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]',
);
}
});
test('run in parallel', () async {
await Future.wait(List.generate(10, (i) => i).map((i) async {
final data = randomBytes(i);
expect(
toHex(md5.convert(data).bytes),
toHex(crypto.md5.convert(data).bytes),
reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]',
);
}));
});
});
}

View file

@ -0,0 +1,62 @@
// Copyright (c) 2023, Sudipto Chandra
// All rights reserved. Check LICENSE file for details.
// ignore_for_file: library_annotations
@Tags(['vm-only'])
import 'package:crypto/crypto.dart' as crypto;
import 'package:hashlib/codecs.dart';
import 'package:hashlib/hashlib.dart';
import 'package:hashlib/random.dart';
import 'package:test/test.dart';
void main() {
group('SHA-224 comparison', () {
test('against known implementations', () {
for (int i = 0; i < 100; ++i) {
final data = randomBytes(i);
expect(
toHex(sha224.convert(data).bytes),
toHex(crypto.sha224.convert(data).bytes),
reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]',
);
}
});
test('run in parallel', () async {
await Future.wait(List.generate(10, (i) => i).map((i) async {
final data = randomBytes(i);
expect(
toHex(sha224.convert(data).bytes),
toHex(crypto.sha224.convert(data).bytes),
reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]',
);
}));
});
group('SHA-256 comparison', () {
test('against known implementations', () {
for (int i = 0; i < 100; ++i) {
final data = randomBytes(i);
expect(
toHex(sha256.convert(data).bytes),
toHex(crypto.sha256.convert(data).bytes),
reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]',
);
}
});
test('run in parallel', () async {
await Future.wait(List.generate(10, (i) => i).map((i) async {
final data = randomBytes(i);
expect(
toHex(sha256.convert(data).bytes),
toHex(crypto.sha256.convert(data).bytes),
reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]',
);
}));
});
});
});
}

View file

@ -0,0 +1,38 @@
// Copyright (c) 2023, Sudipto Chandra
// All rights reserved. Check LICENSE file for details.
// ignore_for_file: library_annotations
@Tags(['vm-only'])
import 'package:crypto/crypto.dart' as crypto;
import 'package:hashlib/codecs.dart';
import 'package:hashlib/hashlib.dart';
import 'package:hashlib/random.dart';
import 'package:test/test.dart';
void main() {
group('SHA-384 comparison', () {
test('against known implementations', () {
for (int i = 0; i < 100; ++i) {
final data = randomBytes(i);
expect(
toHex(sha384.convert(data).bytes),
toHex(crypto.sha384.convert(data).bytes),
reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]',
);
}
});
test('run in parallel', () async {
await Future.wait(List.generate(10, (i) => i).map((i) async {
final data = randomBytes(i);
expect(
toHex(sha384.convert(data).bytes),
toHex(crypto.sha384.convert(data).bytes),
reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]',
);
}));
});
});
}

View file

@ -0,0 +1,38 @@
// Copyright (c) 2023, Sudipto Chandra
// All rights reserved. Check LICENSE file for details.
// ignore_for_file: library_annotations
@Tags(['vm-only'])
import 'package:crypto/crypto.dart' as crypto;
import 'package:hashlib/codecs.dart';
import 'package:hashlib/hashlib.dart';
import 'package:hashlib/random.dart';
import 'package:test/test.dart';
void main() {
group('SHA-512/224 comparison', () {
test('with known implementations', () {
for (int i = 0; i < 100; ++i) {
final data = randomBytes(i);
expect(
toHex(sha512t224.convert(data).bytes),
toHex(crypto.sha512224.convert(data).bytes),
reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]',
);
}
});
test('run in parallel', () async {
await Future.wait(List.generate(10, (i) => i).map((i) async {
final data = randomBytes(i);
expect(
toHex(sha512t224.convert(data).bytes),
toHex(crypto.sha512224.convert(data).bytes),
reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]',
);
}));
});
});
}

View file

@ -0,0 +1,38 @@
// Copyright (c) 2023, Sudipto Chandra
// All rights reserved. Check LICENSE file for details.
// ignore_for_file: library_annotations
@Tags(['vm-only'])
import 'package:crypto/crypto.dart' as crypto;
import 'package:hashlib/codecs.dart';
import 'package:hashlib/hashlib.dart';
import 'package:hashlib/random.dart';
import 'package:test/test.dart';
void main() {
group('SHA-512/256 comparison', () {
test('with known implementations', () {
for (int i = 0; i < 100; ++i) {
final data = randomBytes(i);
expect(
toHex(sha512t256.convert(data).bytes),
toHex(crypto.sha512256.convert(data).bytes),
reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]',
);
}
});
test('run in parallel', () async {
await Future.wait(List.generate(10, (i) => i).map((i) async {
final data = randomBytes(i);
expect(
toHex(sha512t256.convert(data).bytes),
toHex(crypto.sha512256.convert(data).bytes),
reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]',
);
}));
});
});
}

View file

@ -0,0 +1,38 @@
// Copyright (c) 2023, Sudipto Chandra
// All rights reserved. Check LICENSE file for details.
// ignore_for_file: library_annotations
@Tags(['vm-only'])
import 'package:crypto/crypto.dart' as crypto;
import 'package:hashlib/codecs.dart';
import 'package:hashlib/hashlib.dart';
import 'package:hashlib/random.dart';
import 'package:test/test.dart';
void main() {
group('SHA-512 comparison', () {
test('with known implementations', () {
for (int i = 0; i < 100; ++i) {
final data = randomBytes(i);
expect(
toHex(sha512.convert(data).bytes),
toHex(crypto.sha512.convert(data).bytes),
reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]',
);
}
});
test('run in parallel', () async {
await Future.wait(List.generate(10, (i) => i).map((i) async {
final data = randomBytes(i);
expect(
toHex(sha512.convert(data).bytes),
toHex(crypto.sha512.convert(data).bytes),
reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]',
);
}));
});
});
}

View file

@ -0,0 +1,36 @@
// Copyright (c) 2023, Sudipto Chandra
// All rights reserved. Check LICENSE file for details.
// ignore_for_file: library_annotations
@Tags(['vm-only'])
import 'dart:io';
import 'package:hashlib/codecs.dart';
import 'package:hashlib/hashlib.dart';
import 'package:hashlib/random.dart';
import 'package:pointycastle/digests/sm3.dart' as pc_sm3;
import 'package:test/test.dart';
void main() {
group('SM3 comparison', () {
test('with pointy-castle', () {
for (int i = 0; i < 100; ++i) {
final data = randomBytes(i);
expect(
sm3.convert(data).hex(),
toHex(pc_sm3.SM3Digest().process(data)),
reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]',
);
}
});
test('for a file sync', () {
var file = File('LICENSE');
var hash = pc_sm3.SM3Digest().process(file.readAsBytesSync());
var hash2 = sm3.fileSync(file);
expect(hash2.hex(), toHex(hash));
}, tags: 'vm-only');
});
}

View file

@ -1,432 +0,0 @@
// Copyright (c) 2023, Sudipto Chandra
// All rights reserved. Check LICENSE file for details.
// ignore_for_file: library_annotations
@Tags(['vm-only'])
import 'dart:io';
import 'dart:typed_data';
import 'package:crypto/crypto.dart' as crypto;
import 'package:hashlib/codecs.dart';
import 'package:hashlib/hashlib.dart';
import 'package:hashlib/random.dart';
import 'package:pointycastle/digests/blake2b.dart' as pc_blake2b;
import 'package:pointycastle/digests/keccak.dart' as pc_keccak;
import 'package:pointycastle/digests/md4.dart' as pc_md4;
import 'package:pointycastle/digests/sha3.dart' as pc_sha3;
import 'package:pointycastle/digests/sm3.dart' as pc_sm3;
import 'package:test/test.dart';
void main() {
group('blake2b512 comparison', () {
test('with pointycastle', () {
for (int i = 0; i < 100; ++i) {
final data = randomBytes(i);
final out1 = blake2b512.convert(data).hex();
final out2 = toHex(
pc_blake2b.Blake2bDigest(digestSize: 64).process(data),
);
expect(out1, equals(out2), reason: 'size: $i');
}
});
test('with pointycastle with key', () {
final key = randomBytes(16);
for (int i = 0; i < 100; ++i) {
final data = randomBytes(i);
final out1 = blake2b512.mac.by(key).convert(data).hex();
final out2 = toHex(
pc_blake2b.Blake2bDigest(digestSize: 64, key: key).process(data),
);
expect(out1, equals(out2), reason: 'size: $i');
}
});
test('with pointycastle with salt', () {
final salt = randomBytes(16);
for (int i = 0; i < 100; ++i) {
final data = randomBytes(i);
final out1 = Blake2b(64, salt: salt).convert(data).hex();
final out2 = toHex(
pc_blake2b.Blake2bDigest(digestSize: 64, salt: salt).process(data),
);
expect(out1, equals(out2), reason: 'size: $i');
}
});
test('with pointycastle with personalization', () {
final personalization = randomBytes(16);
for (int i = 0; i < 100; ++i) {
final data = randomBytes(i);
final out1 = Blake2b(
64,
aad: personalization,
).convert(data).hex();
final out2 = toHex(
pc_blake2b.Blake2bDigest(
digestSize: 64,
personalization: personalization,
).process(data),
);
expect(out1, equals(out2), reason: 'size: $i');
}
});
test('with pointycastle with salt and personalization', () {
final salt = randomBytes(16);
final personalization = randomBytes(16);
for (int i = 0; i < 100; ++i) {
final data = randomBytes(i);
final out1 = Blake2b(
64,
salt: salt,
aad: personalization,
).convert(data).hex();
final out2 = toHex(
pc_blake2b.Blake2bDigest(
digestSize: 64,
salt: salt,
personalization: personalization,
).process(data),
);
expect(out1, equals(out2), reason: 'size: $i');
}
});
test('with pointycastle with key, salt and personalization', () {
final key = randomBytes(16);
final salt = randomBytes(16);
final aad = randomBytes(16);
for (int i = 0; i < 100; ++i) {
final data = randomBytes(i);
final out1 = Blake2b(64).mac.by(key, salt: salt, aad: aad).hex(data);
final out2 = toHex(
pc_blake2b.Blake2bDigest(
digestSize: 64,
key: key,
salt: salt,
personalization: aad,
).process(data),
);
expect(out1, equals(out2), reason: 'size: $i');
}
});
});
group('HMAC comparison', () {
test('with crypto for MD5', () {
var key = "key";
var msg = "The quick brown fox jumps over the lazy dog";
var expected = "80070713463e7749b90c2dc24911e275";
var actual = toHex(
md5.hmac.byString(key).convert(msg.codeUnits).bytes,
);
var actual2 = toHex(
crypto.Hmac(crypto.md5, key.codeUnits).convert(msg.codeUnits).bytes,
);
expect(actual2, expected, reason: "Key: $key | Message: $msg");
expect(actual, expected, reason: "Key: $key | Message: $msg");
});
test('with crypto', () {
for (int i = 0; i < 100; ++i) {
final data = randomBytes(i);
final key = randomBytes(i & 0x7F);
expect(
toHex(sha1.hmac.by(key).convert(data).bytes),
toHex(crypto.Hmac(crypto.sha1, key).convert(data).bytes),
reason: 'Key: "${String.fromCharCodes(key)}" [${key.length}]\n'
'Message: "${String.fromCharCodes(data)}" [${data.length}]',
);
}
});
test('run in parallel', () async {
await Future.wait(List.generate(10, (i) => i).map((i) async {
final data = randomBytes(i);
final key = randomBytes(i & 0x7F);
expect(
toHex(sha384.hmac.by(key).convert(data).bytes),
toHex(crypto.Hmac(crypto.sha384, key).convert(data).bytes),
reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]',
);
}));
});
});
group('Keccak comparison', () {
test('with keccak256', () {
for (int i = 0; i < 100; ++i) {
final data = randomBytes(i);
var pc = pc_keccak.KeccakDigest(256);
var other = pc.process(Uint8List.fromList(data));
expect(
keccak256.convert(data).hex(),
toHex(other),
reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]',
);
}
});
test('with sha3', () {
for (int i = 0; i < 100; ++i) {
final data = randomBytes(i);
var pc = pc_sha3.SHA3Digest(256);
var other = pc.process(Uint8List.fromList(data));
expect(
sha3_256.convert(data).hex(),
toHex(other),
reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]',
);
}
});
});
group('MD5 comparison', () {
test('for a file async', () async {
var file = File('LICENSE');
var hash = await crypto.md5.bind(file.openRead()).first;
var hash2 = await md5.file(file);
expect(hash2.hex(), toHex(hash.bytes));
}, tags: 'vm-only');
test('for a file sync', () async {
var file = File('LICENSE');
var hash = await crypto.md5.bind(file.openRead()).first;
var hash2 = md5.fileSync(file);
expect(hash2.hex(), toHex(hash.bytes));
}, tags: 'vm-only');
test('with crypto', () {
for (int i = 0; i < 100; ++i) {
final data = randomBytes(i);
expect(
toHex(md5.convert(data).bytes),
toHex(crypto.md5.convert(data).bytes),
reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]',
);
}
});
test('run in parallel', () async {
await Future.wait(List.generate(10, (i) => i).map((i) async {
final data = randomBytes(i);
expect(
toHex(md5.convert(data).bytes),
toHex(crypto.md5.convert(data).bytes),
reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]',
);
}));
});
});
group('MD4 comparison', () {
test('with pointy-castle', () {
for (int i = 0; i < 100; ++i) {
final data = randomBytes(i);
expect(
toHex(md4.convert(data).bytes),
toHex(pc_md4.MD4Digest().process(data)),
reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]',
);
}
});
test('for a file sync', () {
var file = File('LICENSE');
var hash = pc_md4.MD4Digest().process(file.readAsBytesSync());
var hash2 = md4.fileSync(file);
expect(hash2.hex(), toHex(hash));
}, tags: 'vm-only');
});
group('SM3 comparison', () {
test('with pointy-castle', () {
for (int i = 0; i < 100; ++i) {
final data = randomBytes(i);
expect(
sm3.convert(data).hex(),
toHex(pc_sm3.SM3Digest().process(data)),
reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]',
);
}
});
test('for a file sync', () {
var file = File('LICENSE');
var hash = pc_sm3.SM3Digest().process(file.readAsBytesSync());
var hash2 = sm3.fileSync(file);
expect(hash2.hex(), toHex(hash));
}, tags: 'vm-only');
});
group('SHA1 comparison', () {
test('against known implementations', () {
for (int i = 0; i < 100; ++i) {
final data = randomBytes(i);
expect(
toHex(sha1.convert(data).bytes),
toHex(crypto.sha1.convert(data).bytes),
reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]',
);
}
});
test('run in parallel', () async {
await Future.wait(List.generate(10, (i) => i).map((i) async {
final data = randomBytes(i);
expect(
toHex(sha1.convert(data).bytes),
toHex(crypto.sha1.convert(data).bytes),
reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]',
);
}));
});
});
group('SHA-224 comparison', () {
test('against known implementations', () {
for (int i = 0; i < 100; ++i) {
final data = randomBytes(i);
expect(
toHex(sha224.convert(data).bytes),
toHex(crypto.sha224.convert(data).bytes),
reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]',
);
}
});
test('run in parallel', () async {
await Future.wait(List.generate(10, (i) => i).map((i) async {
final data = randomBytes(i);
expect(
toHex(sha224.convert(data).bytes),
toHex(crypto.sha224.convert(data).bytes),
reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]',
);
}));
});
group('SHA-256 comparison', () {
test('against known implementations', () {
for (int i = 0; i < 100; ++i) {
final data = randomBytes(i);
expect(
toHex(sha256.convert(data).bytes),
toHex(crypto.sha256.convert(data).bytes),
reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]',
);
}
});
test('run in parallel', () async {
await Future.wait(List.generate(10, (i) => i).map((i) async {
final data = randomBytes(i);
expect(
toHex(sha256.convert(data).bytes),
toHex(crypto.sha256.convert(data).bytes),
reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]',
);
}));
});
});
});
group('SHA-384 comparison', () {
test('against known implementations', () {
for (int i = 0; i < 100; ++i) {
final data = randomBytes(i);
expect(
toHex(sha384.convert(data).bytes),
toHex(crypto.sha384.convert(data).bytes),
reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]',
);
}
});
test('run in parallel', () async {
await Future.wait(List.generate(10, (i) => i).map((i) async {
final data = randomBytes(i);
expect(
toHex(sha384.convert(data).bytes),
toHex(crypto.sha384.convert(data).bytes),
reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]',
);
}));
});
});
group('SHA-512/224 comparison', () {
test('with known implementations', () {
for (int i = 0; i < 100; ++i) {
final data = randomBytes(i);
expect(
toHex(sha512t224.convert(data).bytes),
toHex(crypto.sha512224.convert(data).bytes),
reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]',
);
}
});
test('run in parallel', () async {
await Future.wait(List.generate(10, (i) => i).map((i) async {
final data = randomBytes(i);
expect(
toHex(sha512t224.convert(data).bytes),
toHex(crypto.sha512224.convert(data).bytes),
reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]',
);
}));
});
});
group('SHA-512/256 comparison', () {
test('with known implementations', () {
for (int i = 0; i < 100; ++i) {
final data = randomBytes(i);
expect(
toHex(sha512t256.convert(data).bytes),
toHex(crypto.sha512256.convert(data).bytes),
reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]',
);
}
});
test('run in parallel', () async {
await Future.wait(List.generate(10, (i) => i).map((i) async {
final data = randomBytes(i);
expect(
toHex(sha512t256.convert(data).bytes),
toHex(crypto.sha512256.convert(data).bytes),
reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]',
);
}));
});
});
group('SHA-512 comparison', () {
test('with known implementations', () {
for (int i = 0; i < 100; ++i) {
final data = randomBytes(i);
expect(
toHex(sha512.convert(data).bytes),
toHex(crypto.sha512.convert(data).bytes),
reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]',
);
}
});
test('run in parallel', () async {
await Future.wait(List.generate(10, (i) => i).map((i) async {
final data = randomBytes(i);
expect(
toHex(sha512.convert(data).bytes),
toHex(crypto.sha512.convert(data).bytes),
reason: 'Message: "${String.fromCharCodes(data)}" [${data.length}]',
);
}));
});
});
}

View file

@ -146,7 +146,7 @@ void main() {
'f4fd0a0cb3bf9c9dc04e3f177936249ac87d619ed41b6b05d2d6dfe95d32153338b' 'f4fd0a0cb3bf9c9dc04e3f177936249ac87d619ed41b6b05d2d6dfe95d32153338b'
'c03c4b68fd46e13c9c0e7f7946ee6856cf068f1702e2fbd98'; 'c03c4b68fd46e13c9c0e7f7946ee6856cf068f1702e2fbd98';
expect(hash.hex(), matcher); expect(hash.hex(), matcher);
}); }, skip: true);
test("with security", () { test("with security", () {
var hash = scrypt( var hash = scrypt(

View file

@ -28,8 +28,8 @@ final tests = {
"e0afca6342847c80827fdc511f0004e53239d3c2f82f67ddd8185bef", "e0afca6342847c80827fdc511f0004e53239d3c2f82f67ddd8185bef",
List.filled(511, "a").join(): List.filled(511, "a").join():
"6eb1c24577241c0871ec3ab020786f59cecb2edb6acef2d483051d6a", "6eb1c24577241c0871ec3ab020786f59cecb2edb6acef2d483051d6a",
List.filled(1000000, "a").join(): // List.filled(1000000, "a").join():
"20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67", // "20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67",
}; };
void main() { void main() {

View file

@ -28,8 +28,8 @@ final tests = {
"02425c0f5b0dabf3d2b9115f3f7723a02ad8bcfb1534a0d231614fd42b8188f6", "02425c0f5b0dabf3d2b9115f3f7723a02ad8bcfb1534a0d231614fd42b8188f6",
List.filled(511, "a").join(): List.filled(511, "a").join():
"058fc5084b6355a06099bfef3de8e360344046dc5a47026de47470b9aabb5bfd", "058fc5084b6355a06099bfef3de8e360344046dc5a47026de47470b9aabb5bfd",
List.filled(1000000, "a").join(): // List.filled(1000000, "a").join():
"cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0", // "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0",
}; };
void main() { void main() {

View file

@ -34,9 +34,9 @@ final tests = {
List.filled(511, "a").join(): List.filled(511, "a").join():
"db100a1eed3842c61d73064b62543cd4531dafa8bfecf6f27d" "db100a1eed3842c61d73064b62543cd4531dafa8bfecf6f27d"
"cfdebbaf60ea14563ea1b486e4f6b9a14fcb0dac05c5f2", "cfdebbaf60ea14563ea1b486e4f6b9a14fcb0dac05c5f2",
List.filled(1000000, "a").join(): // List.filled(1000000, "a").join():
"9d0e1809716474cb086e834e310a4a1ced149e9c00f2485279" // "9d0e1809716474cb086e834e310a4a1ced149e9c00f2485279"
"72cec5704c2a5b07b8b3dc38ecc4ebae97ddd87f3d8985", // "72cec5704c2a5b07b8b3dc38ecc4ebae97ddd87f3d8985",
}; };
void main() { void main() {

View file

@ -16,6 +16,8 @@ final tests = {
"944cd2847fb54558d4775db0485a50003111c8e5daa63fe722c6aa37", "944cd2847fb54558d4775db0485a50003111c8e5daa63fe722c6aa37",
"The quick brown fox jumps over the lazy cog": "The quick brown fox jumps over the lazy cog":
"2b9d6565a7e40f780ba8ab7c8dcf41e3ed3b77997f4c55aa987eede5", "2b9d6565a7e40f780ba8ab7c8dcf41e3ed3b77997f4c55aa987eede5",
List.filled(112, "a").join():
"79b41fef2a0439d2705724a67615f7bcbcd2bf5664a7774b80818eb6",
List.filled(512, "a").join(): List.filled(512, "a").join():
"057bab73fa47ac3e597a34d02c1e285e2d5d8a2e90c9079f549b4af6", "057bab73fa47ac3e597a34d02c1e285e2d5d8a2e90c9079f549b4af6",
List.filled(128, "a").join(): List.filled(128, "a").join():
@ -24,10 +26,8 @@ final tests = {
"502ec9656e1e0b96f9a2699c04cec265edc690b729c45037c6b37a00", "502ec9656e1e0b96f9a2699c04cec265edc690b729c45037c6b37a00",
List.filled(511, "a").join(): List.filled(511, "a").join():
"bd0452a57045c857de05b1c1d94fb49624b00ceaf0ec4c0d4d656a89", "bd0452a57045c857de05b1c1d94fb49624b00ceaf0ec4c0d4d656a89",
List.filled(1000000, "a").join(): // List.filled(1000000, "a").join():
"37ab331d76f0d36de422bd0edeb22a28accd487b7a8453ae965dd287", // "37ab331d76f0d36de422bd0edeb22a28accd487b7a8453ae965dd287",
List.filled(112, "a").join():
"79b41fef2a0439d2705724a67615f7bcbcd2bf5664a7774b80818eb6",
}; };
void main() { void main() {

View file

@ -16,6 +16,8 @@ final tests = {
"dd9d67b371519c339ed8dbd25af90e976a1eeefd4ad3d889005e532fc5bef04d", "dd9d67b371519c339ed8dbd25af90e976a1eeefd4ad3d889005e532fc5bef04d",
"The quick brown fox jumps over the lazy cog": "The quick brown fox jumps over the lazy cog":
"cc8d255a7f2f38fd50388fd1f65ea7910835c5c1e73da46fba01ea50d5dd76fb", "cc8d255a7f2f38fd50388fd1f65ea7910835c5c1e73da46fba01ea50d5dd76fb",
List.filled(112, "a").join():
"9216b5303edb66504570bee90e48ea5beaa5e9fe9f760bbd3e0460559fc005f6",
List.filled(512, "a").join(): List.filled(512, "a").join():
"092b65b92e80ccf4c66683684fb02da4567160534abede190e9b2edef6156839", "092b65b92e80ccf4c66683684fb02da4567160534abede190e9b2edef6156839",
List.filled(128, "a").join(): List.filled(128, "a").join():
@ -24,10 +26,8 @@ final tests = {
"a59cf33e5ad3e70d4962adbb833d021eafa48f85dd9788f84fca4cf762c5f1c7", "a59cf33e5ad3e70d4962adbb833d021eafa48f85dd9788f84fca4cf762c5f1c7",
List.filled(511, "a").join(): List.filled(511, "a").join():
"7e627ccc0719192627fcf9f3987d3da9a61f261a09580371e1ea4622b8ccfcc8", "7e627ccc0719192627fcf9f3987d3da9a61f261a09580371e1ea4622b8ccfcc8",
List.filled(1000000, "a").join(): // List.filled(1000000, "a").join():
"9a59a052930187a97038cae692f30708aa6491923ef5194394dc68d56c74fb21", // "9a59a052930187a97038cae692f30708aa6491923ef5194394dc68d56c74fb21",
List.filled(112, "a").join():
"9216b5303edb66504570bee90e48ea5beaa5e9fe9f760bbd3e0460559fc005f6",
}; };
void main() { void main() {

View file

@ -22,6 +22,9 @@ final tests = {
"The quick brown fox jumps over the lazy cog": "The quick brown fox jumps over the lazy cog":
"3eeee1d0e11733ef152a6c29503b3ae20c4f1f3cda4cb26f1bc1a41f91c7fe4a" "3eeee1d0e11733ef152a6c29503b3ae20c4f1f3cda4cb26f1bc1a41f91c7fe4a"
"b3bd86494049e201c4bd5155f31ecb7a3c8606843c4cc8dfcab7da11c8ae5045", "b3bd86494049e201c4bd5155f31ecb7a3c8606843c4cc8dfcab7da11c8ae5045",
List.filled(112, "a").join():
"c01d080efd492776a1c43bd23dd99d0a2e626d481e16782e75d54c2503b5dc32"
"bd05f0f1ba33e568b88fd2d970929b719ecbb152f58f130a407c8830604b70ca",
List.filled(512, "a").join(): List.filled(512, "a").join():
"0210d27bcbe05c2156627c5f136ade1338ab98e06a4591a00b0bcaa61662a593" "0210d27bcbe05c2156627c5f136ade1338ab98e06a4591a00b0bcaa61662a593"
"1d0b3bd41a67b5c140627923f5f6307669eb508d8db38b2a8cd41aebd783394b", "1d0b3bd41a67b5c140627923f5f6307669eb508d8db38b2a8cd41aebd783394b",
@ -34,12 +37,9 @@ final tests = {
List.filled(511, "a").join(): List.filled(511, "a").join():
"fe32a1f497ce532d041889133436c7086ea40410af5728a6b958aa4a169de44e" "fe32a1f497ce532d041889133436c7086ea40410af5728a6b958aa4a169de44e"
"3884311461188be5f65e79b9a53d010d8347ac20118e4e05df787a17ba71204b", "3884311461188be5f65e79b9a53d010d8347ac20118e4e05df787a17ba71204b",
List.filled(1000000, "a").join(): // List.filled(1000000, "a").join():
"e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973eb" // "e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973eb"
"de0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b", // "de0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b",
List.filled(112, "a").join():
"c01d080efd492776a1c43bd23dd99d0a2e626d481e16782e75d54c2503b5dc32"
"bd05f0f1ba33e568b88fd2d970929b719ecbb152f58f130a407c8830604b70ca",
}; };
void main() { void main() {

View file

@ -34,8 +34,8 @@ final tests = {
"97baef04b5211a439b17eb067ad904e52b12058d7510669ad29b63b9d4609479", "97baef04b5211a439b17eb067ad904e52b12058d7510669ad29b63b9d4609479",
List.filled(511, "a").join(): List.filled(511, "a").join():
"5f4141700026fec7880a6d1d5f34dcc9253dea2df32928f71bc93860d675b38c", "5f4141700026fec7880a6d1d5f34dcc9253dea2df32928f71bc93860d675b38c",
List.filled(1000000, "a").join(): // List.filled(1000000, "a").join():
"c8aaf89429554029e231941a2acc0ad61ff2a5acd8fadd25847a3a732b3b02c3", // "c8aaf89429554029e231941a2acc0ad61ff2a5acd8fadd25847a3a732b3b02c3",
}; };
void main() { void main() {

View file

@ -2,14 +2,14 @@ group 'com.flutterplaza.no_screenshot'
version '1.0-SNAPSHOT' version '1.0-SNAPSHOT'
buildscript { buildscript {
ext.kotlin_version = '1.6.10' ext.kotlin_version = '2.1.0'
repositories { repositories {
google() google()
mavenCentral() mavenCentral()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:7.1.3' classpath 'com.android.tools.build:gradle:8.6.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
} }
} }
@ -26,7 +26,7 @@ apply plugin: 'kotlin-android'
android { android {
namespace "com.flutterplaza.no_screenshot" namespace "com.flutterplaza.no_screenshot"
compileSdkVersion 31 compileSdk 36
compileOptions { compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8 sourceCompatibility JavaVersion.VERSION_1_8

View file

@ -1,8 +1,8 @@
name: no_screenshot name: no_screenshot
description: Flutter plugin to enable, disable, toggle or stream screenshot activities in your application. description: Flutter plugin to enable, disable, toggle or stream screenshot activities in your application.
version: 0.3.2-beta.3 version: 0.3.2
homepage: https://flutterplaza.com homepage: https://flutterplaza.com
repository: https://github.com/FlutterPlaza/no_screenshot/releases/tag/v0.3.2-beta.3 repository: https://github.com/FlutterPlaza/no_screenshot/releases/tag/v0.3.2
environment: environment:
sdk: '>=3.0.0 <4.0.0' sdk: '>=3.0.0 <4.0.0'
@ -16,7 +16,7 @@ dependencies:
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
sdk: flutter sdk: flutter
flutter_lints: ^4.0.0 flutter_lints: ">=4.0.0 <6.0.0"
flutter_driver: flutter_driver:
sdk: flutter sdk: flutter