Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
seleniumhq
GitHub Repository: seleniumhq/selenium
Path: blob/trunk/third_party/closure/goog/crypt/ctr.js
2868 views
1
// Copyright 2016 The Closure Library Authors. All Rights Reserved.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
// http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS-IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
goog.provide('goog.crypt.Ctr');
16
17
goog.require('goog.array');
18
goog.require('goog.asserts');
19
goog.require('goog.crypt');
20
21
/**
22
* Implementation of Ctr mode for block ciphers. See
23
* http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation
24
* #Cipher-block_chaining_.28Ctr.29. for an overview, and
25
* http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
26
* for the spec.
27
*
28
* @param {!goog.crypt.BlockCipher} cipher The block cipher to use.
29
* @constructor
30
* @final
31
* @struct
32
*/
33
goog.crypt.Ctr = function(cipher) {
34
35
/**
36
* Block cipher.
37
* @type {!goog.crypt.BlockCipher}
38
* @private
39
*/
40
this.cipher_ = cipher;
41
};
42
43
/**
44
* Encrypts a message.
45
*
46
* @param {!Array<number>|!Uint8Array} plainText Message to encrypt. An array of
47
* bytes. The length does not have to be a multiple of the blocksize.
48
* @param {!Array<number>|!Uint8Array} initialVector Initial vector for the Ctr
49
* mode. An array of bytes with the same length as the block size, that
50
* should be not reused when using the same key.
51
* @return {!Array<number>} Encrypted message.
52
*/
53
goog.crypt.Ctr.prototype.encrypt = function(plainText, initialVector) {
54
55
goog.asserts.assert(
56
initialVector.length == this.cipher_.BLOCK_SIZE,
57
'Initial vector must be size of one block.');
58
59
// Copy the IV, so it's not modified.
60
var counter = goog.array.clone(initialVector);
61
62
var keyStreamBlock = [];
63
var encryptedArray = [];
64
var plainTextBlock = [];
65
66
while (encryptedArray.length < plainText.length) {
67
keyStreamBlock = this.cipher_.encrypt(counter);
68
goog.crypt.Ctr.incrementBigEndianCounter_(counter);
69
70
plainTextBlock = goog.array.slice(
71
plainText, encryptedArray.length,
72
encryptedArray.length + this.cipher_.BLOCK_SIZE);
73
goog.array.extend(
74
encryptedArray,
75
goog.crypt.xorByteArray(
76
plainTextBlock,
77
goog.array.slice(keyStreamBlock, 0, plainTextBlock.length)));
78
}
79
80
return encryptedArray;
81
};
82
83
84
/**
85
* Decrypts a message. In CTR, this is the same as encrypting.
86
*
87
* @param {!Array<number>|!Uint8Array} cipherText Message to decrypt. The length
88
* does not have to be a multiple of the blocksize.
89
* @param {!Array<number>|!Uint8Array} initialVector Initial vector for the Ctr
90
* mode. An array of bytes with the same length as the block size.
91
* @return {!Array<number>} Decrypted message.
92
*/
93
goog.crypt.Ctr.prototype.decrypt = goog.crypt.Ctr.prototype.encrypt;
94
95
/**
96
* Increments the big-endian integer represented in counter in-place.
97
*
98
* @param {!Array<number>|!Uint8Array} counter The array of bytes to modify.
99
* @private
100
*/
101
goog.crypt.Ctr.incrementBigEndianCounter_ = function(counter) {
102
for (var i = counter.length - 1; i >= 0; i--) {
103
var currentByte = counter[i];
104
currentByte = (currentByte + 1) & 0xFF; // Allow wrapping around.
105
counter[i] = currentByte;
106
if (currentByte != 0) {
107
// This iteration hasn't wrapped around, which means there is
108
// no carry to add to the next byte.
109
return;
110
} // else, repeat with next byte.
111
}
112
};
113
114