in cvs/trilead-ssh2-build213/src/com/trilead/ssh2/crypto/digest/SHA1.java [240:594]
private final void perform()
{
for (int t = 16; t < 80; t++)
{
int x = w[t - 3] ^ w[t - 8] ^ w[t - 14] ^ w[t - 16];
w[t] = ((x << 1) | (x >>> 31));
}
int A = H0;
int B = H1;
int C = H2;
int D = H3;
int E = H4;
/* Here we use variable substitution and loop unrolling
*
* === Original step:
*
* T = s5(A) + f(B,C,D) + E + w[0] + K;
* E = D; D = C; C = s30(B); B = A; A = T;
*
* === Rewritten step:
*
* T = s5(A + f(B,C,D) + E + w[0] + K;
* B = s30(B);
* E = D; D = C; C = B; B = A; A = T;
*
* === Let's rewrite things, introducing new variables:
*
* E0 = E; D0 = D; C0 = C; B0 = B; A0 = A;
*
* T = s5(A0) + f(B0,C0,D0) + E0 + w[0] + K;
* B0 = s30(B0);
* E1 = D0; D1 = C0; C1 = B0; B1 = A0; A1 = T;
*
* T = s5(A1) + f(B1,C1,D1) + E1 + w[1] + K;
* B1 = s30(B1);
* E2 = D1; D2 = C1; C2 = B1; B2 = A1; A2 = T;
*
* E = E2; D = E2; C = C2; B = B2; A = A2;
*
* === No need for 'T', we can write into 'Ex' instead since
* after the calculation of 'T' nobody is interested
* in 'Ex' anymore.
*
* E0 = E; D0 = D; C0 = C; B0 = B; A0 = A;
*
* E0 = E0 + s5(A0) + f(B0,C0,D0) + w[0] + K;
* B0 = s30(B0);
* E1 = D0; D1 = C0; C1 = B0; B1 = A0; A1 = E0;
*
* E1 = E1 + s5(A1) + f(B1,C1,D1) + w[1] + K;
* B1 = s30(B1);
* E2 = D1; D2 = C1; C2 = B1; B2 = A1; A2 = E1;
*
* E = Ex; D = Ex; C = Cx; B = Bx; A = Ax;
*
* === Further optimization: get rid of the swap operations
* Idea: instead of swapping the variables, swap the names of
* the used variables in the next step:
*
* E0 = E; D0 = d; C0 = C; B0 = B; A0 = A;
*
* E0 = E0 + s5(A0) + f(B0,C0,D0) + w[0] + K;
* B0 = s30(B0);
* // E1 = D0; D1 = C0; C1 = B0; B1 = A0; A1 = E0;
*
* D0 = D0 + s5(E0) + f(A0,B0,C0) + w[1] + K;
* A0 = s30(A0);
* E2 = C0; D2 = B0; C2 = A0; B2 = E0; A2 = D0;
*
* E = E2; D = D2; C = C2; B = B2; A = A2;
*
* === OK, let's do this several times, also, directly
* use A (instead of A0) and B,C,D,E.
*
* E = E + s5(A) + f(B,C,D) + w[0] + K;
* B = s30(B);
* // E1 = D; D1 = C; C1 = B; B1 = A; A1 = E;
*
* D = D + s5(E) + f(A,B,C) + w[1] + K;
* A = s30(A);
* // E2 = C; D2 = B; C2 = A; B2 = E; A2 = D;
*
* C = C + s5(D) + f(E,A,B) + w[2] + K;
* E = s30(E);
* // E3 = B; D3 = A; C3 = E; B3 = D; A3 = C;
*
* B = B + s5(C) + f(D,E,A) + w[3] + K;
* D = s30(D);
* // E4 = A; D4 = E; C4 = D; B4 = C; A4 = B;
*
* A = A + s5(B) + f(C,D,E) + w[4] + K;
* C = s30(C);
* // E5 = E; D5 = D; C5 = C; B5 = B; A5 = A;
*
* //E = E5; D = D5; C = C5; B = B5; A = A5;
*
* === Very nice, after 5 steps each variable
* has the same contents as after 5 steps with
* the original algorithm!
*
* We therefore can easily unroll each interval,
* as the number of steps in each interval is a
* multiple of 5 (20 steps per interval).
*/
E += ((A << 5) | (A >>> 27)) + ((B & C) | ((~B) & D)) + w[0] + 0x5A827999;
B = ((B << 30) | (B >>> 2));
D += ((E << 5) | (E >>> 27)) + ((A & B) | ((~A) & C)) + w[1] + 0x5A827999;
A = ((A << 30) | (A >>> 2));
C += ((D << 5) | (D >>> 27)) + ((E & A) | ((~E) & B)) + w[2] + 0x5A827999;
E = ((E << 30) | (E >>> 2));
B += ((C << 5) | (C >>> 27)) + ((D & E) | ((~D) & A)) + w[3] + 0x5A827999;
D = ((D << 30) | (D >>> 2));
A += ((B << 5) | (B >>> 27)) + ((C & D) | ((~C) & E)) + w[4] + 0x5A827999;
C = ((C << 30) | (C >>> 2));
E += ((A << 5) | (A >>> 27)) + ((B & C) | ((~B) & D)) + w[5] + 0x5A827999;
B = ((B << 30) | (B >>> 2));
D += ((E << 5) | (E >>> 27)) + ((A & B) | ((~A) & C)) + w[6] + 0x5A827999;
A = ((A << 30) | (A >>> 2));
C += ((D << 5) | (D >>> 27)) + ((E & A) | ((~E) & B)) + w[7] + 0x5A827999;
E = ((E << 30) | (E >>> 2));
B += ((C << 5) | (C >>> 27)) + ((D & E) | ((~D) & A)) + w[8] + 0x5A827999;
D = ((D << 30) | (D >>> 2));
A += ((B << 5) | (B >>> 27)) + ((C & D) | ((~C) & E)) + w[9] + 0x5A827999;
C = ((C << 30) | (C >>> 2));
E += ((A << 5) | (A >>> 27)) + ((B & C) | ((~B) & D)) + w[10] + 0x5A827999;
B = ((B << 30) | (B >>> 2));
D += ((E << 5) | (E >>> 27)) + ((A & B) | ((~A) & C)) + w[11] + 0x5A827999;
A = ((A << 30) | (A >>> 2));
C += ((D << 5) | (D >>> 27)) + ((E & A) | ((~E) & B)) + w[12] + 0x5A827999;
E = ((E << 30) | (E >>> 2));
B += ((C << 5) | (C >>> 27)) + ((D & E) | ((~D) & A)) + w[13] + 0x5A827999;
D = ((D << 30) | (D >>> 2));
A += ((B << 5) | (B >>> 27)) + ((C & D) | ((~C) & E)) + w[14] + 0x5A827999;
C = ((C << 30) | (C >>> 2));
E += ((A << 5) | (A >>> 27)) + ((B & C) | ((~B) & D)) + w[15] + 0x5A827999;
B = ((B << 30) | (B >>> 2));
D += ((E << 5) | (E >>> 27)) + ((A & B) | ((~A) & C)) + w[16] + 0x5A827999;
A = ((A << 30) | (A >>> 2));
C += ((D << 5) | (D >>> 27)) + ((E & A) | ((~E) & B)) + w[17] + 0x5A827999;
E = ((E << 30) | (E >>> 2));
B += ((C << 5) | (C >>> 27)) + ((D & E) | ((~D) & A)) + w[18] + 0x5A827999;
D = ((D << 30) | (D >>> 2));
A += ((B << 5) | (B >>> 27)) + ((C & D) | ((~C) & E)) + w[19] + 0x5A827999;
C = ((C << 30) | (C >>> 2));
E += ((A << 5) | (A >>> 27)) + (B ^ C ^ D) + w[20] + 0x6ED9EBA1;
B = ((B << 30) | (B >>> 2));
D += ((E << 5) | (E >>> 27)) + (A ^ B ^ C) + w[21] + 0x6ED9EBA1;
A = ((A << 30) | (A >>> 2));
C += ((D << 5) | (D >>> 27)) + (E ^ A ^ B) + w[22] + 0x6ED9EBA1;
E = ((E << 30) | (E >>> 2));
B += ((C << 5) | (C >>> 27)) + (D ^ E ^ A) + w[23] + 0x6ED9EBA1;
D = ((D << 30) | (D >>> 2));
A += ((B << 5) | (B >>> 27)) + (C ^ D ^ E) + w[24] + 0x6ED9EBA1;
C = ((C << 30) | (C >>> 2));
E += ((A << 5) | (A >>> 27)) + (B ^ C ^ D) + w[25] + 0x6ED9EBA1;
B = ((B << 30) | (B >>> 2));
D += ((E << 5) | (E >>> 27)) + (A ^ B ^ C) + w[26] + 0x6ED9EBA1;
A = ((A << 30) | (A >>> 2));
C += ((D << 5) | (D >>> 27)) + (E ^ A ^ B) + w[27] + 0x6ED9EBA1;
E = ((E << 30) | (E >>> 2));
B += ((C << 5) | (C >>> 27)) + (D ^ E ^ A) + w[28] + 0x6ED9EBA1;
D = ((D << 30) | (D >>> 2));
A += ((B << 5) | (B >>> 27)) + (C ^ D ^ E) + w[29] + 0x6ED9EBA1;
C = ((C << 30) | (C >>> 2));
E += ((A << 5) | (A >>> 27)) + (B ^ C ^ D) + w[30] + 0x6ED9EBA1;
B = ((B << 30) | (B >>> 2));
D += ((E << 5) | (E >>> 27)) + (A ^ B ^ C) + w[31] + 0x6ED9EBA1;
A = ((A << 30) | (A >>> 2));
C += ((D << 5) | (D >>> 27)) + (E ^ A ^ B) + w[32] + 0x6ED9EBA1;
E = ((E << 30) | (E >>> 2));
B += ((C << 5) | (C >>> 27)) + (D ^ E ^ A) + w[33] + 0x6ED9EBA1;
D = ((D << 30) | (D >>> 2));
A += ((B << 5) | (B >>> 27)) + (C ^ D ^ E) + w[34] + 0x6ED9EBA1;
C = ((C << 30) | (C >>> 2));
E += ((A << 5) | (A >>> 27)) + (B ^ C ^ D) + w[35] + 0x6ED9EBA1;
B = ((B << 30) | (B >>> 2));
D += ((E << 5) | (E >>> 27)) + (A ^ B ^ C) + w[36] + 0x6ED9EBA1;
A = ((A << 30) | (A >>> 2));
C += ((D << 5) | (D >>> 27)) + (E ^ A ^ B) + w[37] + 0x6ED9EBA1;
E = ((E << 30) | (E >>> 2));
B += ((C << 5) | (C >>> 27)) + (D ^ E ^ A) + w[38] + 0x6ED9EBA1;
D = ((D << 30) | (D >>> 2));
A += ((B << 5) | (B >>> 27)) + (C ^ D ^ E) + w[39] + 0x6ED9EBA1;
C = ((C << 30) | (C >>> 2));
E += ((A << 5) | (A >>> 27)) + ((B & C) | (B & D) | (C & D)) + w[40] + 0x8F1BBCDC;
B = ((B << 30) | (B >>> 2));
D += ((E << 5) | (E >>> 27)) + ((A & B) | (A & C) | (B & C)) + w[41] + 0x8F1BBCDC;
A = ((A << 30) | (A >>> 2));
C += ((D << 5) | (D >>> 27)) + ((E & A) | (E & B) | (A & B)) + w[42] + 0x8F1BBCDC;
E = ((E << 30) | (E >>> 2));
B += ((C << 5) | (C >>> 27)) + ((D & E) | (D & A) | (E & A)) + w[43] + 0x8F1BBCDC;
D = ((D << 30) | (D >>> 2));
A += ((B << 5) | (B >>> 27)) + ((C & D) | (C & E) | (D & E)) + w[44] + 0x8F1BBCDC;
C = ((C << 30) | (C >>> 2));
E += ((A << 5) | (A >>> 27)) + ((B & C) | (B & D) | (C & D)) + w[45] + 0x8F1BBCDC;
B = ((B << 30) | (B >>> 2));
D += ((E << 5) | (E >>> 27)) + ((A & B) | (A & C) | (B & C)) + w[46] + 0x8F1BBCDC;
A = ((A << 30) | (A >>> 2));
C += ((D << 5) | (D >>> 27)) + ((E & A) | (E & B) | (A & B)) + w[47] + 0x8F1BBCDC;
E = ((E << 30) | (E >>> 2));
B += ((C << 5) | (C >>> 27)) + ((D & E) | (D & A) | (E & A)) + w[48] + 0x8F1BBCDC;
D = ((D << 30) | (D >>> 2));
A += ((B << 5) | (B >>> 27)) + ((C & D) | (C & E) | (D & E)) + w[49] + 0x8F1BBCDC;
C = ((C << 30) | (C >>> 2));
E += ((A << 5) | (A >>> 27)) + ((B & C) | (B & D) | (C & D)) + w[50] + 0x8F1BBCDC;
B = ((B << 30) | (B >>> 2));
D += ((E << 5) | (E >>> 27)) + ((A & B) | (A & C) | (B & C)) + w[51] + 0x8F1BBCDC;
A = ((A << 30) | (A >>> 2));
C += ((D << 5) | (D >>> 27)) + ((E & A) | (E & B) | (A & B)) + w[52] + 0x8F1BBCDC;
E = ((E << 30) | (E >>> 2));
B += ((C << 5) | (C >>> 27)) + ((D & E) | (D & A) | (E & A)) + w[53] + 0x8F1BBCDC;
D = ((D << 30) | (D >>> 2));
A += ((B << 5) | (B >>> 27)) + ((C & D) | (C & E) | (D & E)) + w[54] + 0x8F1BBCDC;
C = ((C << 30) | (C >>> 2));
E = E + ((A << 5) | (A >>> 27)) + ((B & C) | (B & D) | (C & D)) + w[55] + 0x8F1BBCDC;
B = ((B << 30) | (B >>> 2));
D += ((E << 5) | (E >>> 27)) + ((A & B) | (A & C) | (B & C)) + w[56] + 0x8F1BBCDC;
A = ((A << 30) | (A >>> 2));
C += ((D << 5) | (D >>> 27)) + ((E & A) | (E & B) | (A & B)) + w[57] + 0x8F1BBCDC;
E = ((E << 30) | (E >>> 2));
B += ((C << 5) | (C >>> 27)) + ((D & E) | (D & A) | (E & A)) + w[58] + 0x8F1BBCDC;
D = ((D << 30) | (D >>> 2));
A += ((B << 5) | (B >>> 27)) + ((C & D) | (C & E) | (D & E)) + w[59] + 0x8F1BBCDC;
C = ((C << 30) | (C >>> 2));
E += ((A << 5) | (A >>> 27)) + (B ^ C ^ D) + w[60] + 0xCA62C1D6;
B = ((B << 30) | (B >>> 2));
D += ((E << 5) | (E >>> 27)) + (A ^ B ^ C) + w[61] + 0xCA62C1D6;
A = ((A << 30) | (A >>> 2));
C += ((D << 5) | (D >>> 27)) + (E ^ A ^ B) + w[62] + 0xCA62C1D6;
E = ((E << 30) | (E >>> 2));
B += ((C << 5) | (C >>> 27)) + (D ^ E ^ A) + w[63] + 0xCA62C1D6;
D = ((D << 30) | (D >>> 2));
A += ((B << 5) | (B >>> 27)) + (C ^ D ^ E) + w[64] + 0xCA62C1D6;
C = ((C << 30) | (C >>> 2));
E += ((A << 5) | (A >>> 27)) + (B ^ C ^ D) + w[65] + 0xCA62C1D6;
B = ((B << 30) | (B >>> 2));
D += ((E << 5) | (E >>> 27)) + (A ^ B ^ C) + w[66] + 0xCA62C1D6;
A = ((A << 30) | (A >>> 2));
C += ((D << 5) | (D >>> 27)) + (E ^ A ^ B) + w[67] + 0xCA62C1D6;
E = ((E << 30) | (E >>> 2));
B += ((C << 5) | (C >>> 27)) + (D ^ E ^ A) + w[68] + 0xCA62C1D6;
D = ((D << 30) | (D >>> 2));
A += ((B << 5) | (B >>> 27)) + (C ^ D ^ E) + w[69] + 0xCA62C1D6;
C = ((C << 30) | (C >>> 2));
E += ((A << 5) | (A >>> 27)) + (B ^ C ^ D) + w[70] + 0xCA62C1D6;
B = ((B << 30) | (B >>> 2));
D += ((E << 5) | (E >>> 27)) + (A ^ B ^ C) + w[71] + 0xCA62C1D6;
A = ((A << 30) | (A >>> 2));
C += ((D << 5) | (D >>> 27)) + (E ^ A ^ B) + w[72] + 0xCA62C1D6;
E = ((E << 30) | (E >>> 2));
B += ((C << 5) | (C >>> 27)) + (D ^ E ^ A) + w[73] + 0xCA62C1D6;
D = ((D << 30) | (D >>> 2));
A += ((B << 5) | (B >>> 27)) + (C ^ D ^ E) + w[74] + 0xCA62C1D6;
C = ((C << 30) | (C >>> 2));
E += ((A << 5) | (A >>> 27)) + (B ^ C ^ D) + w[75] + 0xCA62C1D6;
B = ((B << 30) | (B >>> 2));
D += ((E << 5) | (E >>> 27)) + (A ^ B ^ C) + w[76] + 0xCA62C1D6;
A = ((A << 30) | (A >>> 2));
C += ((D << 5) | (D >>> 27)) + (E ^ A ^ B) + w[77] + 0xCA62C1D6;
E = ((E << 30) | (E >>> 2));
B += ((C << 5) | (C >>> 27)) + (D ^ E ^ A) + w[78] + 0xCA62C1D6;
D = ((D << 30) | (D >>> 2));
A += ((B << 5) | (B >>> 27)) + (C ^ D ^ E) + w[79] + 0xCA62C1D6;
C = ((C << 30) | (C >>> 2));
H0 += A;
H1 += B;
H2 += C;
H3 += D;
H4 += E;
// debug(80, H0, H1, H2, H3, H4);
}