commit | a66bf909d882c24e783be34de4fc0a1b592b928b | [log] [tgz] |
---|---|---|
author | John McDole <john@mcdole.org> | Mon Aug 05 15:43:43 2019 -0700 |
committer | Emily Fortuna <efortuna@google.com> | Mon Aug 05 15:43:43 2019 -0700 |
tree | edb2c5d0a105dfd72364c9abf31c5fe7b801176e | |
parent | a5c46a1ec494c7a4c6fea1910d79bb5c30a47d6a [diff] |
Add missing SHA224, SHA384, and SHA512 (#63) * Add SHA384 and SHA512 Sha384 and Sha512 share the same implementation and differ only in the initailization vectors and the digest concatentation. The algorithm from from rfc6234 calls for 64bit words and operations and to remain dart2js friendly, BigInt was used. INPUT REQUESTED: I'm not sure where the test vectors came from; but a simple comparison to sha384 and sha512 command line methods shows it matching. If you can point me to them, then I can write a better test. * Add Sha224 + Refactor Do something less stupid; use _Sha32BitSink and _Sha64BitSink to have class heirarchies make better sense. * Support 32bit and 64bit operations for SHA384/512 Two modes of operation: if you're in a browser, you get the slower 32bit algorithm because you only have 2^53 bits. If you are on the VM / Flutter, you'll have 64bit operations wich is *much* faster: 32BIT NUMBERS: ~20MB/s hashing Removing BigInt has some good results: Instance of 'Sha224' warmup: 0:00:00.015599 Instance of 'Sha256' warmup: 0:00:00.002325 Instance of 'Sha384' warmup: 0:00:00.019082 Instance of 'Sha512' warmup: 0:00:00.010288 Instance of 'Sha224' real: 0:00:00.092928 Instance of 'Sha256' real: 0:00:00.093426 Instance of 'Sha384' real: 0:00:00.823335 Instance of 'Sha512' real: 0:00:00.807871 64BIT NUMBERS: ~236MB/s hashing On the VM, this is much faster with 64bit operations. Instance of 'Sha224' warmup: 0:00:00.013285 Instance of 'Sha256' warmup: 0:00:00.002443 Instance of 'Sha384' warmup: 0:00:00.020954 Instance of 'Sha512' warmup: 0:00:00.005616 Instance of 'Sha224' real: 0:00:00.097196 Instance of 'Sha256' real: 0:00:00.094167 Instance of 'Sha384' real: 0:00:00.067605 Instance of 'Sha512' real: 0:00:00.067564 NOTE: Compiles with dart2js - cannot reference 64bit hex as the compiler just vomits... but you can left shift by 32. * Fix comment * Add conditional imports * De-listify 32bit allocations Speed is still meh in dart2js: 384/512 numbers: Instance of 'minified:a2' real: 0:00:02.203820 Instance of 'minified:aO' real: 0:00:02.192515 * Add sha monte tests for 224,256,384, and 512 RSP values came from http://csrc.nist.gov/groups/STM/cavp/documents/shs/shabytetestvectors.zip * Fix formattting of lib/crypto.dart * Bump version (adding new features) + min sdk * Bump travis (hidden file) * Rework monte test to function-only.
A set of cryptographic hashing functions implemented in pure Dart
The following hashing algorithms are supported:
To hash a list of bytes, invoke the convert
method on the sha1
, sha256
or md5
objects.
import 'package:crypto/crypto.dart'; import 'dart:convert'; // for the utf8.encode method void main() { var bytes = utf8.encode("foobar"); // data being hashed var digest = sha1.convert(bytes); print("Digest as bytes: ${digest.bytes}"); print("Digest as hex string: $digest"); }
If the input data is not available as a single list of bytes, use the chunked conversion approach.
Invoke the startChunkedConversion
method to create a sink for the input data. On the sink, invoke the add
method for each chunk of input data, and invoke the close
method when all the chunks have been added. The digest can then be retrieved from the Sink<Digest>
used to create the input data sink.
import 'dart:convert'; import 'package:convert/convert.dart'; import 'package:crypto/crypto.dart'; void main() { var firstChunk = utf8.encode("foo"); var secondChunk = utf8.encode("bar"); var output = new AccumulatorSink<Digest>(); var input = sha1.startChunkedConversion(output); input.add(firstChunk); input.add(secondChunk); // call `add` for every chunk of input data input.close(); var digest = output.events.single; print("Digest as bytes: ${digest.bytes}"); print("Digest as hex string: $digest"); }
The above example uses the AccumulatorSink
class that comes with the convert package. It is capable of accumulating multiple events, but in this usage only a single Digest
is added to it when the data sink's close
method is invoked.
Create an instance of the Hmac
class with the hash function and secret key being used. The object can then be used like the other hash calculating objects.
import 'dart:convert'; import 'package:crypto/crypto.dart'; void main() { var key = utf8.encode('p@ssw0rd'); var bytes = utf8.encode("foobar"); var hmacSha256 = new Hmac(sha256, key); // HMAC-SHA256 var digest = hmacSha256.convert(bytes); print("HMAC digest as bytes: ${digest.bytes}"); print("HMAC digest as hex string: $digest"); }
Support for this library is given as best effort.
This library has not been reviewed or vetted by security professionals.
Please file feature requests and bugs at the issue tracker.