@@ -440,23 +440,46 @@ abstract class AesGcm extends Cipher {
440440 }
441441}
442442
443- /// _Argon2id_ ([draft-irtf-cfrg-argon2-03 ] (https://tools .ietf.org/html/draft-irtf-cfrg-argon2-03 ))
444- /// password hashing function.
443+ /// _Argon2id_ ([RFC 9106 ] (https://datatracker .ietf.org/doc/rfc9106/ ))
444+ /// memory-hard password hashing function.
445445///
446- /// _Argon2_ is known for winning _Password Hashing Competition_ 2015. The
447- /// algorithm can provide much better security than older algorithms such as
448- /// [Pbkdf2] .
446+ /// _Argon2_ is known for winning _Password Hashing Competition_ 2015. OWASP
447+ /// [Password Storage Cheat Sheet] (https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html)
448+ /// describes it as first choice for password hashing .
449449///
450- /// By default, [DartArgon2id] , our pure Dart implementation, will be used.
450+ /// The default implementation is [DartArgon2id] , our pure Dart implementation.
451+ ///
452+ /// ## Things to know
453+ /// * You need to choose:
454+ /// * [memory]
455+ /// * Number of 1kB blocks of memory needed to compute the hash.
456+ /// * Higher is better for security. You should experiment what is good
457+ /// for your system. We recommend to start from 1000 (= 1 MB) and go
458+ /// as high as you can.
459+ /// * [parallelism]
460+ /// * Maximum number of parallel computations.
461+ /// * You should choose a small number such as 1 or 4.
462+ /// * [iterations]
463+ /// * Number of iterations. Higher is better for security, but usually
464+ /// you should use value `1` because it makes more sense (from security
465+ /// point of view) to raise [memory] parameter instead.
466+ /// * [hashLength]
467+ /// * The value should be at least 16 bytes. More than 32 bytes is
468+ /// unnecessary from security point of view.
469+ /// * OWASP [suggests] (https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html)
470+ /// the following parameter values:
471+ /// * memory = 19 MiB of memory
472+ /// * parallelism = 1
473+ /// * iterations = 2
451474///
452475/// ## Example
453476/// ```
454477/// import 'package:cryptography/cryptography.dart';
455478///
456479/// Future<void> main() async {
457480/// final algorithm = Argon2id(
458- /// parallelism: 3 ,
459- /// memorySize: 10000000,
481+ /// parallelism: 4 ,
482+ /// memory: 10000, // 10 000 x 1kB block = 10 MB
460483/// iterations: 3,
461484/// hashLength: 32,
462485/// );
@@ -479,13 +502,13 @@ abstract class AesGcm extends Cipher {
479502abstract class Argon2id extends KdfAlgorithm {
480503 factory Argon2id ({
481504 required int parallelism,
482- required int memorySize ,
505+ required int memory ,
483506 required int iterations,
484507 required int hashLength,
485508 }) {
486509 return Cryptography .instance.argon2id (
487510 parallelism: parallelism,
488- memorySize : memorySize ,
511+ memory : memory ,
489512 iterations: iterations,
490513 hashLength: hashLength,
491514 );
@@ -495,31 +518,30 @@ abstract class Argon2id extends KdfAlgorithm {
495518 const Argon2id .constructor ();
496519
497520 @override
498- int get hashCode => parallelism ^ memorySize ^ iterations ^ hashLength;
521+ int get hashCode => parallelism ^ memory ^ iterations ^ hashLength;
499522
500523 /// Hash length.
501524 int get hashLength;
502525
503526 /// Number of iterations.
504527 int get iterations;
505528
506- /// Minimum number of bytes attacker needs to store in memory for each
507- /// attempt.
508- int get memorySize;
529+ /// Minimum number of 1 kB blocks needed to compute the hash.
530+ int get memory;
509531
510532 /// Maximum number of processors attacker can use concurrently for each
511533 /// attempt.
512534 int get parallelism;
513535
514536 /// Argon2id algorithm version number.
515537 @nonVirtual
516- int get version => 0x13 ;
538+ int get version => 19 ;
517539
518540 @override
519541 bool operator == (other) =>
520542 other is Argon2id &&
521543 parallelism == other.parallelism &&
522- memorySize == other.memorySize &&
544+ memory == other.memory &&
523545 iterations == other.iterations &&
524546 hashLength == other.hashLength;
525547
@@ -535,14 +557,14 @@ abstract class Argon2id extends KdfAlgorithm {
535557 Future <SecretKey > deriveKey ({
536558 required SecretKey secretKey,
537559 required List <int > nonce,
538- List <int > k = const < int > [],
539- List <int > ad = const < int > [],
560+ List <int > optionalSecret = const < int > [],
561+ List <int > associatedData = const < int > [],
540562 });
541563
542564 @override
543- String toString () => 'Argon2id (\n '
565+ String toString () => '$ runtimeType (\n '
544566 ' parallelism: $parallelism ,\n '
545- ' memorySize : $memorySize ,\n '
567+ ' memory : $memory ,\n '
546568 ' iterations: $iterations ,\n '
547569 ' hashLength: $hashLength ,\n '
548570 ')' ;
@@ -617,6 +639,19 @@ abstract class Blake2b extends HashAlgorithm implements MacAlgorithm {
617639 }) : assert (hashLengthInBytes > 0 ),
618640 assert (hashLengthInBytes <= defaultHashLengthInBytes);
619641
642+ /// Enables you to replace [hashLengthInBytes] .
643+ ///
644+ /// Subclasses should replace this with their own implementation.
645+ Blake2b replace ({int ? hashLength}) {
646+ hashLength ?? = hashLengthInBytes;
647+ if (hashLength == hashLengthInBytes) {
648+ return this ;
649+ }
650+ return Blake2b (
651+ hashLengthInBytes: hashLength,
652+ );
653+ }
654+
620655 @override
621656 void checkParameters ({
622657 int ? length,
0 commit comments