-
Notifications
You must be signed in to change notification settings - Fork 10.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement the AESBaseCipher
class and let the AES128Cipher
and AES256Cipher
classes extend it
#9412
Conversation
/botio-linux preview |
From: Bot.io (Linux m4)ReceivedCommand cmd_preview from @timvandermeij received. Current queue size: 0 Live output at: http://54.67.70.0:8877/c3b9d9ea39fc88c/output.txt |
From: Bot.io (Linux m4)SuccessFull output at http://54.67.70.0:8877/c3b9d9ea39fc88c/output.txt Total script time: 8.34 mins Published |
/botio test |
From: Bot.io (Linux m4)ReceivedCommand cmd_test from @timvandermeij received. Current queue size: 0 Live output at: http://54.67.70.0:8877/1421af42bbce4f2/output.txt |
From: Bot.io (Windows)ReceivedCommand cmd_test from @timvandermeij received. Current queue size: 0 Live output at: http://54.215.176.217:8877/329cd466fec145f/output.txt |
From: Bot.io (Windows)FailedFull output at http://54.215.176.217:8877/329cd466fec145f/output.txt Total script time: 23.94 mins
Image differences available at: http://54.215.176.217:8877/329cd466fec145f/reftest-analyzer.html#web=eq.log |
From: Bot.io (Linux m4)SuccessFull output at http://54.67.70.0:8877/1421af42bbce4f2/output.txt Total script time: 39.16 mins
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for taking this on, since there's a lot of duplication removed here!
Given that we've thus far avoided using ES6 class
es in src/core/
code, since the performance might still not be on-par with the old way of simulating classes, would it be possible to find a PDF file (e.g. in the test-suite) which make use of either of these algorithms and benchmark the impact of this PR?
Edit: One thing that's probably missing from those instructions, and which I forgot myself once, is that you need to remember to manually re-run gulp generic
before each benchmarking step (since we're now relying on a built pdf.worker.js
file when running tests).
I realize that it may perhaps be difficult to find such a file, but I figured that it cannot hurt to ask.
src/core/crypto.js
Outdated
result[j] = (t4 ^= result[j - 16]); | ||
j++; | ||
class AESBaseCipher { | ||
constructor(key) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't believe that you're using the key
parameter in the base class, so let's remove it both here and at the super()
callsites.
Furthermore, since this should only ever be used as an abstract base class, let's actually enforce that:
constructor() {
if (this.constructor === AESBaseCipher) {
unreachable('Cannot initialize AESBaseCipher.');
}
// The rest of the code goes here...
src/core/crypto.js
Outdated
} | ||
|
||
_expandKey(cipherKey) { | ||
throw new Error('Cannot call `_expandKey` on the base class'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's use unreachable
instead here
src/core/crypto.js
Outdated
decryptBlock(data, finalize, iv = null) { | ||
let i, sourceLength = data.length; | ||
let buffer = this.buffer, bufferLength = this.bufferPosition; | ||
// if not supplied an IV wait for IV values |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While you're here, mind fixing the formatting/grammar of this comment?
src/core/crypto.js
Outdated
for (i = 0; bufferLength < 16 && i < sourceLength; ++i, ++bufferLength) { | ||
buffer[bufferLength] = data[i]; | ||
} | ||
if (bufferLength < 16) { | ||
// need more data | ||
if (bufferLength < 16) { // Need more data. | ||
this.bufferLength = bufferLength; | ||
return new Uint8Array([]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pre-existing nit: This looks weird, let's use new Uint8Array(0);
here and elsewhere instead.
src/core/crypto.js
Outdated
function _decrypt(input, key) { | ||
var state = new Uint8Array(16); | ||
_decrypt(input, key) { | ||
let t, u, v, i, j, k; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Since we're now using let
rather than var
, thanks for that by the way :-), it doesn't seem entirely necessary to define the loop variables (i.e. i
, j
, k
, and so on) in this "method/function global" way any more!?
This probably applies elsewhere too...
…re similar This commit is the first step for extracting a base class for the `AES128Cipher` and the `AES256Cipher` classes. The objective here is to make code changes (not altering the logic) to make the implementations as similar as possible as found by creating a diff of both classes. In particular, we extract the key size and cycles of repetitions constants since they are different for AES-128 and AES-256. Moreover, we rename functions to be similar. In the `AES256Cipher` class, there was an additional assignment to `this` in the decryption function. However, this was unnecessary because the assignment would also be done when the loop was exited.
…ES256Cipher` classes extend it
Thank you for the review! I have made all changes and I did a benchmark of the code. I created the following
Then I ran all benchmarking steps from https://github.com/mozilla/pdf.js/wiki/Benchmarking-your-changes, which I updated to be more step-by-step and to include the
Therefore, we can conclude that this change has no negative performance impact. |
/botio test |
From: Bot.io (Linux m4)ReceivedCommand cmd_test from @Snuffleupagus received. Current queue size: 0 Live output at: http://54.67.70.0:8877/14515caa1b4d8aa/output.txt |
From: Bot.io (Windows)ReceivedCommand cmd_test from @Snuffleupagus received. Current queue size: 0 Live output at: http://54.215.176.217:8877/f1af0452c155fef/output.txt |
From: Bot.io (Windows)FailedFull output at http://54.215.176.217:8877/f1af0452c155fef/output.txt Total script time: 23.81 mins
Image differences available at: http://54.215.176.217:8877/f1af0452c155fef/reftest-analyzer.html#web=eq.log |
From: Bot.io (Linux m4)SuccessFull output at http://54.67.70.0:8877/14515caa1b4d8aa/output.txt Total script time: 38.71 mins
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, thanks for cleaning this up!
Also, thanks's for taking the time to benchmark the changes.
Implement the `AESBaseCipher` class and let the `AES128Cipher` and `AES256Cipher` classes extend it
More information is provided in the commit messages. Unit tests are already available and still pass. I highly recommend to review this per commit instead of looking at the full diff and reviewing the second commit with the
?w=1
flag.The diff of the two classes after the first commit can be found at https://www.diffchecker.com/fBgVIwRm. This clearly shows the amount of code duplication and that basically everything can live in the base class except for
_expandKey
. ThedecryptBlock
differences are resolved by taking the one for AES-256 in the base class and setting theiv
parameter tonull
by default so that for AES-128 nothing changes.Fixes #5155.