1d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger/*
2d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger * Copyright 2013 Google Inc.
3d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger *
4d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be
5d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger * found in the LICENSE file.
6d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger *
7d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger * The following code is based on the description in RFC 3174.
8d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger * http://www.ietf.org/rfc/rfc3174.txt
9d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger */
10d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
11d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#include "SkTypes.h"
12d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#include "SkSHA1.h"
13d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#include <string.h>
14d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
15d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger/** SHA1 basic transformation. Transforms state based on block. */
16d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergerstatic void transform(uint32_t state[5], const uint8_t block[64]);
17d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
18d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger/** Encodes input into output (5 big endian 32 bit values). */
19d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergerstatic void encode(uint8_t output[20], const uint32_t input[5]);
20d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
21d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger/** Encodes input into output (big endian 64 bit value). */
22d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergerstatic void encode(uint8_t output[8], const uint64_t input);
23d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
24d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek SollenbergerSkSHA1::SkSHA1() : byteCount(0) {
25d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    // These are magic numbers from the specification. The first four are the same as MD5.
26d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    this->state[0] = 0x67452301;
27d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    this->state[1] = 0xefcdab89;
28d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    this->state[2] = 0x98badcfe;
29d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    this->state[3] = 0x10325476;
30d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    this->state[4] = 0xc3d2e1f0;
31d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger}
32d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
33d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergervoid SkSHA1::update(const uint8_t* input, size_t inputLength) {
34d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    unsigned int bufferIndex = (unsigned int)(this->byteCount & 0x3F);
35d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    unsigned int bufferAvailable = 64 - bufferIndex;
36d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
37d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    unsigned int inputIndex;
38d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    if (inputLength >= bufferAvailable) {
39d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        if (bufferIndex) {
40d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger            memcpy(&this->buffer[bufferIndex], input, bufferAvailable);
41d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger            transform(this->state, this->buffer);
42d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger            inputIndex = bufferAvailable;
43d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        } else {
44d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger            inputIndex = 0;
45d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        }
46d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
47d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        for (; inputIndex + 63 < inputLength; inputIndex += 64) {
48d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger            transform(this->state, &input[inputIndex]);
49d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        }
50d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
51d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        bufferIndex = 0;
52d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    } else {
53d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        inputIndex = 0;
54d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    }
55d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
56d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    memcpy(&this->buffer[bufferIndex], &input[inputIndex], inputLength - inputIndex);
57d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
58d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    this->byteCount += inputLength;
59d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger}
60d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
61d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergervoid SkSHA1::finish(Digest& digest) {
62d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    // Get the number of bits before padding.
63d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    uint8_t bits[8];
64d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    encode(bits, this->byteCount << 3);
65d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
66d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    // Pad out to 56 mod 64.
67d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    unsigned int bufferIndex = (unsigned int)(this->byteCount & 0x3F);
68d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    unsigned int paddingLength = (bufferIndex < 56) ? (56 - bufferIndex) : (120 - bufferIndex);
69d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    static uint8_t PADDING[64] = {
70d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
71d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger           0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
72d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger           0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
73d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger           0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
74d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    };
75d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    this->update(PADDING, paddingLength);
76d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
77d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    // Append length (length before padding, will cause final update).
78d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    this->update(bits, 8);
79d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
80d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    // Write out digest.
81d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    encode(digest.data, this->state);
82d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
83d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#if defined(SK_SHA1_CLEAR_DATA)
84d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    // Clear state.
85d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    memset(this, 0, sizeof(*this));
86d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#endif
87d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger}
88d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
89d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergerstruct F1 { uint32_t operator()(uint32_t B, uint32_t C, uint32_t D) {
90d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    return (B & C) | ((~B) & D);
91d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    //return D ^ (B & (C ^ D));
92d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    //return (B & C) ^ ((~B) & D);
93d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    //return (B & C) + ((~B) & D);
94d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    //return _mm_or_ps(_mm_andnot_ps(B, D), _mm_and_ps(B, C)); //SSE2
95d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    //return vec_sel(D, C, B); //PPC
96d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger}};
97d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
98d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergerstruct F2 { uint32_t operator()(uint32_t B, uint32_t C, uint32_t D) {
99d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    return B ^ C ^ D;
100d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger}};
101d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
102d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergerstruct F3 { uint32_t operator()(uint32_t B, uint32_t C, uint32_t D) {
103d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    return (B & C) | (B & D) | (C & D);
104d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    //return (B & C) | (D & (B | C));
105d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    //return (B & C) | (D & (B ^ C));
106d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    //return (B & C) + (D & (B ^ C));
107d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    //return (B & C) ^ (B & D) ^ (C & D);
108d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger}};
109d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
110d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger/** Rotates x left n bits. */
111d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergerstatic inline uint32_t rotate_left(uint32_t x, uint8_t n) {
112d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    return (x << n) | (x >> (32 - n));
113d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger}
114d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
115d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergertemplate <typename T>
116d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergerstatic inline void operation(T operation,
117d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger                             uint32_t A, uint32_t& B, uint32_t C, uint32_t D, uint32_t& E,
118d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger                             uint32_t w, uint32_t k) {
119d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    E += rotate_left(A, 5) + operation(B, C, D) + w + k;
120d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    B = rotate_left(B, 30);
121d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger}
122d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
123d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergerstatic void transform(uint32_t state[5], const uint8_t block[64]) {
124d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    uint32_t A = state[0], B = state[1], C = state[2], D = state[3], E = state[4];
125d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
126d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    // Round constants defined in SHA-1.
127d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    static const uint32_t K[] = {
128d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        0x5A827999, //sqrt(2) * 2^30
129d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        0x6ED9EBA1, //sqrt(3) * 2^30
130d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        0x8F1BBCDC, //sqrt(5) * 2^30
131d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        0xCA62C1D6, //sqrt(10) * 2^30
132d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    };
133d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
134d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    uint32_t W[80];
135d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
136d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    // Initialize the array W.
137d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    size_t i = 0;
138d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    for (size_t j = 0; i < 16; ++i, j += 4) {
139d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        W[i] = (((uint32_t)block[j  ]) << 24) |
140d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger               (((uint32_t)block[j+1]) << 16) |
141d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger               (((uint32_t)block[j+2]) <<  8) |
142d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger               (((uint32_t)block[j+3])      );
143d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    }
144d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    for (; i < 80; ++i) {
145d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger       W[i] = rotate_left(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1);
146d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger       //The following is equivelent and speeds up SSE implementations, but slows non-SSE.
147d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger       //W[i] = rotate_left(W[i-6] ^ W[i-16] ^ W[i-28] ^ W[i-32], 2);
148d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    }
149d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
150d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    // Round 1
151d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F1(), A, B, C, D, E, W[ 0], K[0]);
152d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F1(), E, A, B, C, D, W[ 1], K[0]);
153d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F1(), D, E, A, B, C, W[ 2], K[0]);
154d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F1(), C, D, E, A, B, W[ 3], K[0]);
155d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F1(), B, C, D, E, A, W[ 4], K[0]);
156d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F1(), A, B, C, D, E, W[ 5], K[0]);
157d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F1(), E, A, B, C, D, W[ 6], K[0]);
158d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F1(), D, E, A, B, C, W[ 7], K[0]);
159d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F1(), C, D, E, A, B, W[ 8], K[0]);
160d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F1(), B, C, D, E, A, W[ 9], K[0]);
161d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F1(), A, B, C, D, E, W[10], K[0]);
162d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F1(), E, A, B, C, D, W[11], K[0]);
163d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F1(), D, E, A, B, C, W[12], K[0]);
164d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F1(), C, D, E, A, B, W[13], K[0]);
165d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F1(), B, C, D, E, A, W[14], K[0]);
166d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F1(), A, B, C, D, E, W[15], K[0]);
167d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F1(), E, A, B, C, D, W[16], K[0]);
168d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F1(), D, E, A, B, C, W[17], K[0]);
169d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F1(), C, D, E, A, B, W[18], K[0]);
170d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F1(), B, C, D, E, A, W[19], K[0]);
171d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
172d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    // Round 2
173d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F2(), A, B, C, D, E, W[20], K[1]);
174d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F2(), E, A, B, C, D, W[21], K[1]);
175d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F2(), D, E, A, B, C, W[22], K[1]);
176d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F2(), C, D, E, A, B, W[23], K[1]);
177d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F2(), B, C, D, E, A, W[24], K[1]);
178d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F2(), A, B, C, D, E, W[25], K[1]);
179d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F2(), E, A, B, C, D, W[26], K[1]);
180d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F2(), D, E, A, B, C, W[27], K[1]);
181d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F2(), C, D, E, A, B, W[28], K[1]);
182d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F2(), B, C, D, E, A, W[29], K[1]);
183d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F2(), A, B, C, D, E, W[30], K[1]);
184d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F2(), E, A, B, C, D, W[31], K[1]);
185d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F2(), D, E, A, B, C, W[32], K[1]);
186d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F2(), C, D, E, A, B, W[33], K[1]);
187d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F2(), B, C, D, E, A, W[34], K[1]);
188d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F2(), A, B, C, D, E, W[35], K[1]);
189d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F2(), E, A, B, C, D, W[36], K[1]);
190d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F2(), D, E, A, B, C, W[37], K[1]);
191d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F2(), C, D, E, A, B, W[38], K[1]);
192d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F2(), B, C, D, E, A, W[39], K[1]);
193d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
194d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    // Round 3
195d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F3(), A, B, C, D, E, W[40], K[2]);
196d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F3(), E, A, B, C, D, W[41], K[2]);
197d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F3(), D, E, A, B, C, W[42], K[2]);
198d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F3(), C, D, E, A, B, W[43], K[2]);
199d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F3(), B, C, D, E, A, W[44], K[2]);
200d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F3(), A, B, C, D, E, W[45], K[2]);
201d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F3(), E, A, B, C, D, W[46], K[2]);
202d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F3(), D, E, A, B, C, W[47], K[2]);
203d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F3(), C, D, E, A, B, W[48], K[2]);
204d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F3(), B, C, D, E, A, W[49], K[2]);
205d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F3(), A, B, C, D, E, W[50], K[2]);
206d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F3(), E, A, B, C, D, W[51], K[2]);
207d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F3(), D, E, A, B, C, W[52], K[2]);
208d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F3(), C, D, E, A, B, W[53], K[2]);
209d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F3(), B, C, D, E, A, W[54], K[2]);
210d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F3(), A, B, C, D, E, W[55], K[2]);
211d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F3(), E, A, B, C, D, W[56], K[2]);
212d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F3(), D, E, A, B, C, W[57], K[2]);
213d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F3(), C, D, E, A, B, W[58], K[2]);
214d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F3(), B, C, D, E, A, W[59], K[2]);
215d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
216d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    // Round 4
217d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F2(), A, B, C, D, E, W[60], K[3]);
218d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F2(), E, A, B, C, D, W[61], K[3]);
219d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F2(), D, E, A, B, C, W[62], K[3]);
220d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F2(), C, D, E, A, B, W[63], K[3]);
221d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F2(), B, C, D, E, A, W[64], K[3]);
222d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F2(), A, B, C, D, E, W[65], K[3]);
223d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F2(), E, A, B, C, D, W[66], K[3]);
224d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F2(), D, E, A, B, C, W[67], K[3]);
225d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F2(), C, D, E, A, B, W[68], K[3]);
226d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F2(), B, C, D, E, A, W[69], K[3]);
227d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F2(), A, B, C, D, E, W[70], K[3]);
228d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F2(), E, A, B, C, D, W[71], K[3]);
229d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F2(), D, E, A, B, C, W[72], K[3]);
230d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F2(), C, D, E, A, B, W[73], K[3]);
231d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F2(), B, C, D, E, A, W[74], K[3]);
232d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F2(), A, B, C, D, E, W[75], K[3]);
233d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F2(), E, A, B, C, D, W[76], K[3]);
234d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F2(), D, E, A, B, C, W[77], K[3]);
235d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F2(), C, D, E, A, B, W[78], K[3]);
236d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    operation(F2(), B, C, D, E, A, W[79], K[3]);
237d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
238d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    state[0] += A;
239d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    state[1] += B;
240d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    state[2] += C;
241d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    state[3] += D;
242d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    state[4] += E;
243d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
244d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#if defined(SK_SHA1_CLEAR_DATA)
245d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    // Clear sensitive information.
246d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    memset(W, 0, sizeof(W));
247d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#endif
248d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger}
249d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
250d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergerstatic void encode(uint8_t output[20], const uint32_t input[5]) {
251d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    for (size_t i = 0, j = 0; i < 5; i++, j += 4) {
252d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        output[j  ] = (uint8_t)((input[i] >> 24) & 0xff);
253d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        output[j+1] = (uint8_t)((input[i] >> 16) & 0xff);
254d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        output[j+2] = (uint8_t)((input[i] >>  8) & 0xff);
255d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        output[j+3] = (uint8_t)((input[i]      ) & 0xff);
256d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    }
257d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger}
258d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
259d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergerstatic void encode(uint8_t output[8], const uint64_t input) {
260d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    output[0] = (uint8_t)((input >> 56) & 0xff);
261d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    output[1] = (uint8_t)((input >> 48) & 0xff);
262d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    output[2] = (uint8_t)((input >> 40) & 0xff);
263d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    output[3] = (uint8_t)((input >> 32) & 0xff);
264d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    output[4] = (uint8_t)((input >> 24) & 0xff);
265d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    output[5] = (uint8_t)((input >> 16) & 0xff);
266d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    output[6] = (uint8_t)((input >>  8) & 0xff);
267d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    output[7] = (uint8_t)((input      ) & 0xff);
268d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger}
269