/*
 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

import static java.lang.System.out;

import java.nio.ByteBuffer;
import java.security.DigestException;
import java.security.MessageDigest;
import java.util.Random;

/**
 * @test
 * @bug 8050371
 * @summary Check md.digest(data) value whether same with digest output value
 *          with various update/digest methods.
 * @author Kevin Liu
 */

public class TestSameValue {

    public static void main(String[] args) throws Exception {
        TestSameValue test1 = new TestSameValue();
        test1.run();
    }

    private void run() throws Exception {

        byte[] data = new byte[6706];
        MessageDigest md = null;
        // Initialize input data
        new Random().nextBytes(data);

        String[] providers = {
                null, "SUN"
        };
        String[] algorithmArr = {
                "SHA", "Sha", "MD5", "md5", "SHA-224", "SHA-256", "SHA-384",
                "SHA-512"
        };

        for (String algorithm: algorithmArr) {
            for (String provider: providers) {
                if (provider != null) {
                    md = MessageDigest.getInstance(algorithm, provider);
                } else {
                    md = MessageDigest.getInstance(algorithm);
                }
                for (UpdateDigestMethod updateMethod: UpdateDigestMethod
                        .values()) {
                    byte[] output = updateMethod.updateDigest(data, md);
                    // Get the output and the "correct" one
                    byte[] standard = md.digest(data);
                    // Compare input and output
                    if (!MessageDigest.isEqual(output, standard)) {
                        throw new RuntimeException(
                                "Test failed at algorithm/provider/numUpdate:"
                                        + algorithm + "/" + provider + "/"
                                        + updateMethod);
                    }
                }
            }
        }

        out.println("All " + algorithmArr.length
                * UpdateDigestMethod.values().length * providers.length
                + " tests Passed");
    }

    private static enum UpdateDigestMethod {

        /*
         * update the data one by one using method update(byte input) then
         * do digest (giving the output buffer, offset, and the number of
         * bytes to put in the output buffer)
         */
        UPDATE_DIGEST_BUFFER {
            @Override
            public byte[] updateDigest(byte[] data, MessageDigest md)
                    throws DigestException {
                for (byte element: data) {
                    md.update(element);
                }
                byte[] output = new byte[md.getDigestLength()];
                int len = md.digest(output, 0, output.length);
                if (len != output.length) {
                    throw new RuntimeException(
                        "ERROR" + ": digest length differs!");
                }
                return output;
            }
        },

        /*
         * update the data one by one using method update(byte input)
         * then do digest
         */
        UPDATE_DIGEST {
            @Override
            public byte[] updateDigest(byte[] data, MessageDigest md) {
                for (byte element: data) {
                    md.update(element);
                }
                return md.digest();
            }
        },

        /*
         * update all the data at once as a block, then do digest ( giving the
         * output buffer, offset, and the number of bytes to put in the output
         * buffer)
         */
        UPDATE_BLOCK_DIGEST_BUFFER {
            @Override
            public byte[] updateDigest(byte[] data, MessageDigest md)
                    throws DigestException {
                md.update(data);
                byte[] output = new byte[md.getDigestLength()];
                int len = md.digest(output, 0, output.length);
                if (len != output.length) {
                    throw new RuntimeException(
                        "ERROR" + ": digest length differs!");
                }
                return output;
            }
        },

        // update all the data at once as a block, then do digest
        UPDATE_BLOCK_DIGEST {
            @Override
            public byte[] updateDigest(byte[] data, MessageDigest md) {
                md.update(data);
                return md.digest();
            }
        },

        /*
         * update the leading bytes (length is "data.length-LASTNBYTES")
         * at once as a block, then do digest (do a final update using
         * the left LASTNBYTES bytes which is passed as a parameter for
         * the digest method, then complete the digest)
         */
        UPDATE_LEADING_BLOCK_DIGEST_REMAIN {
            @Override
            public byte[] updateDigest(byte[] data, MessageDigest md) {
                byte[] mainPart = new byte[data.length - LASTNBYTES];
                for (int i = 0; i < mainPart.length; i++) {
                    mainPart[i] = data[i];
                }
                for (int j = 0; j < LASTNBYTES; j++) {
                    REMAIN[j] = data[data.length - LASTNBYTES + j];
                }
                md.update(mainPart);
                return md.digest(REMAIN);
            }
        },

        /*
         * update the data 2 bytes each time, after finishing updating,
         * do digest (giving the output buffer, offset, and the number
         * of bytes to put in the output buffer)
         */
        UPDATE_BYTES_DIGEST_BUFFER {
            @Override
            public byte[] updateDigest(byte[] data, MessageDigest md)
                    throws DigestException {

                for (int i = 0; i < data.length / 2; i++) {
                    md.update(data, i * 2, 2);
                }
                byte[] output = new byte[md.getDigestLength()];
                int len = md.digest(output, 0, output.length);
                if (len != output.length) {
                    throw new RuntimeException(
                        "ERROR" + ": digest length differs!");
                }
                return output;
            }
        },

        /*
         * update the data 2 bytes each time, after finishing updating,
         * do digest
         */
        UPDATE_BYTES_DIGEST {
            @Override
            public byte[] updateDigest(byte[] data, MessageDigest md) {
                for (int i=0;i<data.length/2;i++){
                    md.update(data,i*2,2);
                }
                return md.digest();
            }
        },

        /*
         * update the data one by one using method update(byte[] input,
         * int offset, int len) for the leading bytes (length is
         * "data.length-LASTNBYTES"), then do digest (do a final
         * update using the left LASTNBYTES bytes which is passed
         * as a parameter for digest method then complete the digest)
         */
        UPDATE_BUFFER_LEADING_DIGEST_REMAIN {
            @Override
            public byte[] updateDigest(byte[] data, MessageDigest md) {
                for (int i = 0; i < data.length - LASTNBYTES; i++) {
                    md.update(data, i, 1);
                }
                for (int j = 0; j < LASTNBYTES; j++) {
                    REMAIN[j] = data[data.length - LASTNBYTES + j];
                }
                return md.digest(REMAIN);
            }
        },

        /*
         * update the data one by one using method update(byte input)
         * for the leading bytes (length is "data.length-LASTNBYTES"),
         * then do digest (do a final update using the left LASTNBYTES
         * bytes which is passed as a parameter for digest method,
         * then complete the digest)
         */
        UPDATE_LEADING_DIGEST_REMAIN {
            @Override
            public byte[] updateDigest(byte[] data, MessageDigest md) {
                for (int i = 0; i < data.length - LASTNBYTES; i++) {
                    md.update(data[i]);
                }
                for (int j = 0; j < LASTNBYTES; j++) {
                    REMAIN[j] = data[data.length - LASTNBYTES + j];
                }
                return md.digest(REMAIN);
            }
        },

        /*
         * update all the data at once as a ByteBuffer, then do digest
         * (giving the output buffer, offset, and the number of bytes
         * to put in the output buffer)
         */
        UPDATE_BYTE_BUFFER_DIGEST_BUFFER {
            @Override
            public byte[] updateDigest(byte[] data, MessageDigest md)
                    throws DigestException {
                md.update(ByteBuffer.wrap(data));
                byte[] output = new byte[md.getDigestLength()];
                int len = md.digest(output, 0, output.length);
                if (len != output.length) {
                    throw new RuntimeException(
                          "ERROR" + ": digest length differs!");
                }
                return output;
            }
        },

        // update all the data at once as a ByteBuffer, then do digest
        UPDATE_BYTE_BUFFER_DIGEST {
            @Override
            public byte[] updateDigest(byte[] data, MessageDigest md) {
                md.update(ByteBuffer.wrap(data));
                return md.digest();
            }
        },

        /*
         * update the leading bytes (length is "data.length-LASTNBYTES")
         * at once as a ByteBuffer, then do digest (do a final update
         * using the left LASTNBYTES bytes which is passed as a parameter
         * for the digest method, then complete the digest)
         */
        UPDATE_BYTE_BUFFER_LEADING_DIGEST_REMAIN {
            @Override
            public byte[] updateDigest(byte[] data, MessageDigest md) {
                byte[] mainPart = new byte[data.length - LASTNBYTES];
                for (int i = 0; i < mainPart.length; i++) {
                    mainPart[i] = data[i];
                }
                for (int j = 0; j < LASTNBYTES; j++) {
                    REMAIN[j] = data[data.length - LASTNBYTES + j];
                }
                md.update(ByteBuffer.wrap(mainPart));
                return md.digest(REMAIN);
            }
        };

        private static final int LASTNBYTES = 5;
        private static final byte[] REMAIN = new byte[LASTNBYTES];

        public abstract byte[] updateDigest(byte[] data, MessageDigest md)
                throws DigestException;
    }
}
