11cb0ef41Sopenharmony_ci// META: title=WebCryptoAPI: digest()
21cb0ef41Sopenharmony_ci// META: timeout=long
31cb0ef41Sopenharmony_ci
41cb0ef41Sopenharmony_ci    var subtle = crypto.subtle; // Change to test prefixed implementations
51cb0ef41Sopenharmony_ci
61cb0ef41Sopenharmony_ci    var sourceData = {
71cb0ef41Sopenharmony_ci        empty: new Uint8Array(0),
81cb0ef41Sopenharmony_ci        short: new Uint8Array([21, 110, 234, 124, 193, 76, 86, 203, 148, 219, 3, 10, 74, 157, 149, 255]),
91cb0ef41Sopenharmony_ci        medium: new Uint8Array([182, 200, 249, 223, 100, 140, 208, 136, 183, 15, 56, 231, 65, 151, 177, 140, 184, 30, 30, 67, 80, 213, 11, 204, 184, 251, 90, 115, 121, 200, 123, 178, 227, 214, 237, 84, 97, 237, 30, 159, 54, 243, 64, 163, 150, 42, 68, 107, 129, 91, 121, 75, 75, 212, 58, 68, 3, 80, 32, 119, 178, 37, 108, 200, 7, 131, 127, 58, 172, 209, 24, 235, 75, 156, 43, 174, 184, 151, 6, 134, 37, 171, 172, 161, 147])
101cb0ef41Sopenharmony_ci    };
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_ci    sourceData.long = new Uint8Array(1024 * sourceData.medium.byteLength);
131cb0ef41Sopenharmony_ci    for (var i=0; i<1024; i++) {
141cb0ef41Sopenharmony_ci        sourceData.long.set(sourceData.medium, i * sourceData.medium.byteLength);
151cb0ef41Sopenharmony_ci    }
161cb0ef41Sopenharmony_ci
171cb0ef41Sopenharmony_ci    var digestedData = {
181cb0ef41Sopenharmony_ci        "sha-1": {
191cb0ef41Sopenharmony_ci            empty: new Uint8Array([218, 57, 163, 238, 94, 107, 75, 13, 50, 85, 191, 239, 149, 96, 24, 144, 175, 216, 7, 9]),
201cb0ef41Sopenharmony_ci            short: new Uint8Array([201, 19, 24, 205, 242, 57, 106, 1, 94, 63, 78, 106, 134, 160, 186, 101, 184, 99, 89, 68]),
211cb0ef41Sopenharmony_ci            medium: new Uint8Array([229, 65, 6, 8, 112, 235, 22, 191, 51, 182, 142, 81, 245, 19, 82, 104, 147, 152, 103, 41]),
221cb0ef41Sopenharmony_ci            long: new Uint8Array([48, 152, 181, 0, 55, 236, 208, 46, 189, 101, 118, 83, 178, 191, 160, 30, 238, 39, 162, 234])
231cb0ef41Sopenharmony_ci        },
241cb0ef41Sopenharmony_ci        "sha-256": {
251cb0ef41Sopenharmony_ci            empty: new Uint8Array([227, 176, 196, 66, 152, 252, 28, 20, 154, 251, 244, 200, 153, 111, 185, 36, 39, 174, 65, 228, 100, 155, 147, 76, 164, 149, 153, 27, 120, 82, 184, 85]),
261cb0ef41Sopenharmony_ci            short: new Uint8Array([162, 131, 17, 134, 152, 71, 146, 199, 211, 45, 89, 200, 151, 64, 104, 127, 25, 173, 220, 27, 149, 158, 113, 161, 204, 83, 138, 59, 126, 216, 67, 242]),
271cb0ef41Sopenharmony_ci            medium: new Uint8Array([83, 83, 103, 135, 126, 240, 20, 215, 252, 113, 126, 92, 183, 132, 62, 89, 182, 26, 238, 98, 199, 2, 156, 236, 126, 198, 193, 47, 217, 36, 224, 228]),
281cb0ef41Sopenharmony_ci            long: new Uint8Array([20, 205, 234, 157, 199, 95, 90, 98, 116, 217, 252, 30, 100, 0, 153, 18, 241, 220, 211, 6, 180, 143, 232, 233, 207, 18, 45, 230, 113, 87, 23, 129])
291cb0ef41Sopenharmony_ci        },
301cb0ef41Sopenharmony_ci        "sha-384": {
311cb0ef41Sopenharmony_ci            empty: new Uint8Array([56, 176, 96, 167, 81, 172, 150, 56, 76, 217, 50, 126, 177, 177, 227, 106, 33, 253, 183, 17, 20, 190, 7, 67, 76, 12, 199, 191, 99, 246, 225, 218, 39, 78, 222, 191, 231, 111, 101, 251, 213, 26, 210, 241, 72, 152, 185, 91]),
321cb0ef41Sopenharmony_ci            short: new Uint8Array([107, 245, 234, 101, 36, 209, 205, 220, 67, 247, 207, 59, 86, 238, 5, 146, 39, 64, 74, 47, 83, 143, 2, 42, 61, 183, 68, 122, 120, 44, 6, 193, 237, 5, 232, 171, 79, 94, 220, 23, 243, 113, 20, 64, 223, 233, 119, 49]),
331cb0ef41Sopenharmony_ci            medium: new Uint8Array([203, 194, 197, 136, 254, 91, 37, 249, 22, 218, 40, 180, 228, 122, 72, 74, 230, 252, 31, 228, 144, 45, 213, 201, 147, 154, 107, 253, 3, 74, 179, 180, 139, 57, 8, 116, 54, 1, 31, 106, 153, 135, 157, 39, 149, 64, 233, 119]),
341cb0ef41Sopenharmony_ci            long: new Uint8Array([73, 244, 253, 179, 152, 25, 104, 249, 125, 87, 55, 15, 133, 52, 80, 103, 205, 82, 150, 169, 125, 209, 161, 142, 6, 145, 30, 117, 110, 150, 8, 73, 37, 41, 135, 14, 26, 209, 48, 153, 141, 87, 203, 251, 183, 193, 208, 158])
351cb0ef41Sopenharmony_ci        },
361cb0ef41Sopenharmony_ci        "sha-512": {
371cb0ef41Sopenharmony_ci            empty: new Uint8Array([207, 131, 225, 53, 126, 239, 184, 189, 241, 84, 40, 80, 214, 109, 128, 7, 214, 32, 228, 5, 11, 87, 21, 220, 131, 244, 169, 33, 211, 108, 233, 206, 71, 208, 209, 60, 93, 133, 242, 176, 255, 131, 24, 210, 135, 126, 236, 47, 99, 185, 49, 189, 71, 65, 122, 129, 165, 56, 50, 122, 249, 39, 218, 62]),
381cb0ef41Sopenharmony_ci            short: new Uint8Array([55, 82, 72, 190, 95, 243, 75, 231, 76, 171, 79, 241, 195, 188, 141, 198, 139, 213, 248, 223, 244, 2, 62, 152, 248, 123, 134, 92, 255, 44, 114, 66, 146, 223, 24, 148, 67, 166, 79, 244, 19, 74, 101, 205, 70, 53, 185, 212, 245, 220, 13, 63, 182, 117, 40, 0, 42, 99, 172, 242, 108, 157, 165, 117]),
391cb0ef41Sopenharmony_ci            medium: new Uint8Array([185, 16, 159, 131, 158, 142, 164, 60, 137, 15, 41, 60, 225, 29, 198, 226, 121, 141, 30, 36, 49, 241, 228, 185, 25, 227, 178, 12, 79, 54, 48, 59, 163, 156, 145, 109, 179, 6, 196, 90, 59, 101, 118, 31, 245, 190, 133, 50, 142, 234, 244, 44, 56, 48, 241, 217, 94, 122, 65, 22, 91, 125, 45, 54]),
401cb0ef41Sopenharmony_ci            long: new Uint8Array([75, 2, 202, 246, 80, 39, 96, 48, 234, 86, 23, 229, 151, 197, 213, 63, 217, 218, 166, 139, 120, 191, 230, 11, 34, 170, 184, 211, 106, 76, 42, 58, 255, 219, 113, 35, 79, 73, 39, 103, 55, 197, 117, 221, 247, 77, 20, 5, 76, 189, 111, 219, 152, 253, 13, 220, 188, 180, 111, 145, 173, 118, 182, 238])
411cb0ef41Sopenharmony_ci        },
421cb0ef41Sopenharmony_ci    }
431cb0ef41Sopenharmony_ci
441cb0ef41Sopenharmony_ci    // Try every combination of hash with source data size. Variations tested are
451cb0ef41Sopenharmony_ci    // hash name in upper, lower, or mixed case, and upper-case version with the
461cb0ef41Sopenharmony_ci    // source buffer altered after call.
471cb0ef41Sopenharmony_ci    Object.keys(sourceData).forEach(function(size) {
481cb0ef41Sopenharmony_ci        Object.keys(digestedData).forEach(function(alg) {
491cb0ef41Sopenharmony_ci            var upCase = alg.toUpperCase();
501cb0ef41Sopenharmony_ci            var downCase = alg.toLowerCase();
511cb0ef41Sopenharmony_ci            var mixedCase = upCase.substr(0, 1) + downCase.substr(1);
521cb0ef41Sopenharmony_ci
531cb0ef41Sopenharmony_ci            promise_test(function(test) {
541cb0ef41Sopenharmony_ci                var promise = subtle.digest({name: upCase}, sourceData[size])
551cb0ef41Sopenharmony_ci                .then(function(result) {
561cb0ef41Sopenharmony_ci                    assert_true(equalBuffers(result, digestedData[alg][size]), "digest() yielded expected result for " + alg + ":" + size);
571cb0ef41Sopenharmony_ci                }, function(err) {
581cb0ef41Sopenharmony_ci                    assert_unreached("digest() threw an error for " + alg + ":" + size + " - " + err.message);
591cb0ef41Sopenharmony_ci                });
601cb0ef41Sopenharmony_ci
611cb0ef41Sopenharmony_ci                return promise;
621cb0ef41Sopenharmony_ci            }, upCase + " with " + size + " source data");
631cb0ef41Sopenharmony_ci
641cb0ef41Sopenharmony_ci            promise_test(function(test) {
651cb0ef41Sopenharmony_ci                var promise = subtle.digest({name: downCase}, sourceData[size])
661cb0ef41Sopenharmony_ci                .then(function(result) {
671cb0ef41Sopenharmony_ci                    assert_true(equalBuffers(result, digestedData[alg][size]), "digest() yielded expected result for " + alg + ":" + size);
681cb0ef41Sopenharmony_ci                }, function(err) {
691cb0ef41Sopenharmony_ci                    assert_unreached("digest() threw an error for " + alg + ":" + size + " - " + err.message);
701cb0ef41Sopenharmony_ci                });
711cb0ef41Sopenharmony_ci
721cb0ef41Sopenharmony_ci                return promise;
731cb0ef41Sopenharmony_ci            }, downCase + " with " + size + " source data");
741cb0ef41Sopenharmony_ci
751cb0ef41Sopenharmony_ci            promise_test(function(test) {
761cb0ef41Sopenharmony_ci                var promise = subtle.digest({name: mixedCase}, sourceData[size])
771cb0ef41Sopenharmony_ci                .then(function(result) {
781cb0ef41Sopenharmony_ci                    assert_true(equalBuffers(result, digestedData[alg][size]), "digest() yielded expected result for " + alg + ":" + size);
791cb0ef41Sopenharmony_ci                }, function(err) {
801cb0ef41Sopenharmony_ci                    assert_unreached("digest() threw an error for " + alg + ":" + size + " - " + err.message);
811cb0ef41Sopenharmony_ci                });
821cb0ef41Sopenharmony_ci
831cb0ef41Sopenharmony_ci                return promise;
841cb0ef41Sopenharmony_ci            }, mixedCase + " with " + size + " source data");
851cb0ef41Sopenharmony_ci
861cb0ef41Sopenharmony_ci            promise_test(function(test) {
871cb0ef41Sopenharmony_ci                var copiedBuffer = copyBuffer(sourceData[size]);
881cb0ef41Sopenharmony_ci                var promise = subtle.digest({name: upCase}, copiedBuffer)
891cb0ef41Sopenharmony_ci                .then(function(result) {
901cb0ef41Sopenharmony_ci                    assert_true(equalBuffers(result, digestedData[alg][size]), "digest() yielded expected result for " + alg + ":" + size);
911cb0ef41Sopenharmony_ci                }, function(err) {
921cb0ef41Sopenharmony_ci                    assert_unreached("digest() threw an error for " + alg + ":" + size + " - " + err.message);
931cb0ef41Sopenharmony_ci                });
941cb0ef41Sopenharmony_ci
951cb0ef41Sopenharmony_ci                copiedBuffer[0] = 255 - copiedBuffer;
961cb0ef41Sopenharmony_ci                return promise;
971cb0ef41Sopenharmony_ci            }, upCase + " with " + size + " source data and altered buffer after call");
981cb0ef41Sopenharmony_ci
991cb0ef41Sopenharmony_ci        });
1001cb0ef41Sopenharmony_ci    });
1011cb0ef41Sopenharmony_ci
1021cb0ef41Sopenharmony_ci    // Call digest() with bad algorithm names to get an error
1031cb0ef41Sopenharmony_ci    var badNames = ["AES-GCM", "RSA-OAEP", "PBKDF2", "AES-KW"];
1041cb0ef41Sopenharmony_ci    Object.keys(sourceData).forEach(function(size) {
1051cb0ef41Sopenharmony_ci        badNames.forEach(function(badName) {
1061cb0ef41Sopenharmony_ci
1071cb0ef41Sopenharmony_ci            promise_test(function(test) {
1081cb0ef41Sopenharmony_ci                var promise = subtle.digest({name: badName}, sourceData[size])
1091cb0ef41Sopenharmony_ci                .then(function(result) {
1101cb0ef41Sopenharmony_ci                    assert_unreached("digest() should not have worked for " + badName + ":" + size);
1111cb0ef41Sopenharmony_ci                }, function(err) {
1121cb0ef41Sopenharmony_ci                    assert_equals(err.name, "NotSupportedError", "Bad algorithm name should cause NotSupportedError")
1131cb0ef41Sopenharmony_ci                });
1141cb0ef41Sopenharmony_ci
1151cb0ef41Sopenharmony_ci                return promise;
1161cb0ef41Sopenharmony_ci            }, badName + " with " + size);
1171cb0ef41Sopenharmony_ci
1181cb0ef41Sopenharmony_ci        });
1191cb0ef41Sopenharmony_ci    });
1201cb0ef41Sopenharmony_ci
1211cb0ef41Sopenharmony_ci
1221cb0ef41Sopenharmony_ci    done();
1231cb0ef41Sopenharmony_ci
1241cb0ef41Sopenharmony_ci
1251cb0ef41Sopenharmony_ci    // Returns a copy of the sourceBuffer it is sent.
1261cb0ef41Sopenharmony_ci    function copyBuffer(sourceBuffer) {
1271cb0ef41Sopenharmony_ci        var source = new Uint8Array(sourceBuffer);
1281cb0ef41Sopenharmony_ci        var copy = new Uint8Array(sourceBuffer.byteLength)
1291cb0ef41Sopenharmony_ci
1301cb0ef41Sopenharmony_ci        for (var i=0; i<source.byteLength; i++) {
1311cb0ef41Sopenharmony_ci            copy[i] = source[i];
1321cb0ef41Sopenharmony_ci        }
1331cb0ef41Sopenharmony_ci
1341cb0ef41Sopenharmony_ci        return copy;
1351cb0ef41Sopenharmony_ci    }
1361cb0ef41Sopenharmony_ci
1371cb0ef41Sopenharmony_ci    function equalBuffers(a, b) {
1381cb0ef41Sopenharmony_ci        if (a.byteLength !== b.byteLength) {
1391cb0ef41Sopenharmony_ci            return false;
1401cb0ef41Sopenharmony_ci        }
1411cb0ef41Sopenharmony_ci
1421cb0ef41Sopenharmony_ci        var aBytes = new Uint8Array(a);
1431cb0ef41Sopenharmony_ci        var bBytes = new Uint8Array(b);
1441cb0ef41Sopenharmony_ci
1451cb0ef41Sopenharmony_ci        for (var i=0; i<a.byteLength; i++) {
1461cb0ef41Sopenharmony_ci            if (aBytes[i] !== bBytes[i]) {
1471cb0ef41Sopenharmony_ci                return false;
1481cb0ef41Sopenharmony_ci            }
1491cb0ef41Sopenharmony_ci        }
1501cb0ef41Sopenharmony_ci
1511cb0ef41Sopenharmony_ci        return true;
1521cb0ef41Sopenharmony_ci    }
153