-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Perf improvements for sha1.js, sha2.js, and sha2_64b.js #391
Conversation
closure/goog/crypt/sha1.js: Compute the message schedule on the fly to avoid allocating additional memory (and incurring additional garbage collections) unnecessarily. ~10% speed gain on Chrome 35. closure/goog/crypt/sha1.js: Don't try to process more bytes from the message than the message's length. closure/goog/crypt/sha12mc_test.js: Monte Carlo KATs for SHA-1, SHA2-224, SHA2-256, SHA2-384, and SHA2-512. (Note: this test takes a few minutes.) closure/goog/crypt/sha2.js: Add helper functions for generating and using precomputed message schedules. Port the block-size fast path from Sha1.update to Sha2.update. Compute message schedule on the fly. Remove code for testing for invalid inputs that is not present in Sha1.update. ~40% speed gain on Chrome 35. closure/goog/crypt/sha256_test.html: Remove testBadInput(); no similar test is performed in sha1_test.html closure/goog/crypt/sha256_test.js: Add some KATs. closure/goog/crypt/sha256_test.js: Add test-case for 54-byte message. Add tests for precomputed message schedule case; cleaned up other tests somewhat. closure/goog/crypt/sha256_test.js: Rename tests, synchronize with sha1_test.js. closure/goog/crypt/sha2_64bit.js: Added length fix from sha1.js and sha2.js new ones repeatedly; update message schedule in-place. 20% performance
Perf improvements for sha1.js, sha2.js, and sha2_64b.js
@coruus @meheffernan This PR causes at least five unit tests to fail:
I've rewritten the history of the project so that this PR was never merged. We need a better process for testing PRs before merging, to avoid headaches like this. |
Hmm. I'm somewhat perplexed: When I tested this recently, I'm fairly Is this on a specific target, or all targets? I know that all tests were passing on V8/amd64 when I first submitted the In that thread, there was a mention of some platform-specific issues, Do you have a preferred CI setup that I can test against? |
@coruus In order to land this PR, you'll need to point me to a CI setup showing all Closure unit tests passing. I'd like to set up Travis for this project, but I can't commit to doing it anytime soon. Maybe you can help? |
Sounds like fun.
|
Hmm. So, actually, the problem was fairly trivial (and not platform-specific). Here's the diff: diff --git a/closure/goog/crypt/sha1.js b/closure/goog/crypt/sha1.js
index a1979ea..a96cc96 100644
--- a/closure/goog/crypt/sha1.js
+++ b/closure/goog/crypt/sha1.js
@@ -179,7 +179,7 @@ goog.crypt.Sha1.prototype.compress_ = function(buf, opt_offset) {
// performance by about 10% on Chrome 35.
for (i = 16; i < 80; i++) {
t = W[(i - 3) & 15] ^ W[(i - 8) & 15] ^ W[(i - 14) & 15] ^ W[i & 15];
- W[i & 15] = (((t << 1) | (t >>> 31)) & 0xfffffff) | 0;
+ W[i & 15] = (((t << 1) | (t >>> 31)) & 0xffffffff) | 0;
if (i < 40) {
if (i < 20) {
f = d ^ (b & (c ^ d));
@@ -206,11 +206,11 @@ goog.crypt.Sha1.prototype.compress_ = function(buf, opt_offset) {
a = t;
}
- this.chain_[0] = ((this.chain_[0] + a) & 0xfffffff) | 0;
- this.chain_[1] = ((this.chain_[1] + b) & 0xfffffff) | 0;
- this.chain_[2] = ((this.chain_[2] + c) & 0xfffffff) | 0;
- this.chain_[3] = ((this.chain_[3] + d) & 0xfffffff) | 0;
- this.chain_[4] = ((this.chain_[4] + e) & 0xfffffff) | 0;
+ this.chain_[0] = ((this.chain_[0] + a) & 0xffffffff) | 0;
+ this.chain_[1] = ((this.chain_[1] + b) & 0xffffffff) | 0;
+ this.chain_[2] = ((this.chain_[2] + c) & 0xffffffff) | 0;
+ this.chain_[3] = ((this.chain_[3] + d) & 0xffffffff) | 0;
+ this.chain_[4] = ((this.chain_[4] + e) & 0xffffffff) | 0;
}; |
And see #404 for the fixed version. |
Please see #322 for the original PR. This is rebased and squashed.
CC @meheffernan @nanaze
This is rebased and squashed. @nanaze: Are the changes sufficient to make this work on Kindle Fire?