/*
 * Copyright 2005-2006 Sun Microsystems, Inc.  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.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package sun.security.provider;

import java.security.*;

import static sun.security.provider.ByteArrayAccess.*;

/**
 * The MD4 class is used to compute an MD4 message digest over a given
 * buffer of bytes. It is an implementation of the RSA Data Security Inc
 * MD4 algorithim as described in internet RFC 1320.
 *
 * <p>The MD4 algorithm is very weak and should not be used unless it is
 * unavoidable. Therefore, it is not registered in our standard providers. To
 * obtain an implementation, call the static getInstance() method in this
 * class.
 *
 * @author      Andreas Sterbenz
 */
public final class MD4 extends DigestBase {

    // state of this object
    private final int[] state;
    // temporary buffer, used by implCompress()
    private final int[] x;

    // rotation constants
    private static final int S11 = 3;
    private static final int S12 = 7;
    private static final int S13 = 11;
    private static final int S14 = 19;
    private static final int S21 = 3;
    private static final int S22 = 5;
    private static final int S23 = 9;
    private static final int S24 = 13;
    private static final int S31 = 3;
    private static final int S32 = 9;
    private static final int S33 = 11;
    private static final int S34 = 15;

    private final static Provider md4Provider;

    static {
        md4Provider = new Provider("MD4Provider", 1.0d, "MD4 MessageDigest") {};
        AccessController.doPrivileged(new PrivilegedAction<Void>() {
            public Void run() {
                md4Provider.put("MessageDigest.MD4", "sun.security.provider.MD4");
                return null;
            }
        });
    }

    public static MessageDigest getInstance() {
        try {
            return MessageDigest.getInstance("MD4", md4Provider);
        } catch (NoSuchAlgorithmException e) {
            // should never occur
            throw new ProviderException(e);
        }
    }

    // Standard constructor, creates a new MD4 instance.
    public MD4() {
        super("MD4", 16, 64);
        state = new int[4];
        x = new int[16];
        implReset();
    }

    // Cloning constructor
    private MD4(MD4 base) {
        super(base);
        this.state = base.state.clone();
        this.x = new int[16];
    }

    // clone this object
    public Object clone() {
        return new MD4(this);
    }

    /**
     * Reset the state of this object.
     */
    void implReset() {
        // Load magic initialization constants.
        state[0] = 0x67452301;
        state[1] = 0xefcdab89;
        state[2] = 0x98badcfe;
        state[3] = 0x10325476;
    }

    /**
     * Perform the final computations, any buffered bytes are added
     * to the digest, the count is added to the digest, and the resulting
     * digest is stored.
     */
    void implDigest(byte[] out, int ofs) {
        long bitsProcessed = bytesProcessed << 3;

        int index = (int)bytesProcessed & 0x3f;
        int padLen = (index < 56) ? (56 - index) : (120 - index);
        engineUpdate(padding, 0, padLen);

        i2bLittle4((int)bitsProcessed, buffer, 56);
        i2bLittle4((int)(bitsProcessed >>> 32), buffer, 60);
        implCompress(buffer, 0);

        i2bLittle(state, 0, out, ofs, 16);
    }

    private static int FF(int a, int b, int c, int d, int x, int s) {
        a += ((b & c) | ((~b) & d)) + x;
        return ((a << s) | (a >>> (32 - s)));
    }

    private static int GG(int a, int b, int c, int d, int x, int s) {
        a += ((b & c) | (b & d) | (c & d)) + x + 0x5a827999;
        return ((a << s) | (a >>> (32 - s)));
    }

    private static int HH(int a, int b, int c, int d, int x, int s) {
        a += ((b ^ c) ^ d) + x + 0x6ed9eba1;
        return ((a << s) | (a >>> (32 - s)));
    }

    /**
     * This is where the functions come together as the generic MD4
     * transformation operation. It consumes sixteen
     * bytes from the buffer, beginning at the specified offset.
     */
    void implCompress(byte[] buf, int ofs) {
        b2iLittle64(buf, ofs, x);

        int a = state[0];
        int b = state[1];
        int c = state[2];
        int d = state[3];

        /* Round 1 */
        a = FF (a, b, c, d, x[ 0], S11); /* 1 */
        d = FF (d, a, b, c, x[ 1], S12); /* 2 */
        c = FF (c, d, a, b, x[ 2], S13); /* 3 */
        b = FF (b, c, d, a, x[ 3], S14); /* 4 */
        a = FF (a, b, c, d, x[ 4], S11); /* 5 */
        d = FF (d, a, b, c, x[ 5], S12); /* 6 */
        c = FF (c, d, a, b, x[ 6], S13); /* 7 */
        b = FF (b, c, d, a, x[ 7], S14); /* 8 */
        a = FF (a, b, c, d, x[ 8], S11); /* 9 */
        d = FF (d, a, b, c, x[ 9], S12); /* 10 */
        c = FF (c, d, a, b, x[10], S13); /* 11 */
        b = FF (b, c, d, a, x[11], S14); /* 12 */
        a = FF (a, b, c, d, x[12], S11); /* 13 */
        d = FF (d, a, b, c, x[13], S12); /* 14 */
        c = FF (c, d, a, b, x[14], S13); /* 15 */
        b = FF (b, c, d, a, x[15], S14); /* 16 */

        /* Round 2 */
        a = GG (a, b, c, d, x[ 0], S21); /* 17 */
        d = GG (d, a, b, c, x[ 4], S22); /* 18 */
        c = GG (c, d, a, b, x[ 8], S23); /* 19 */
        b = GG (b, c, d, a, x[12], S24); /* 20 */
        a = GG (a, b, c, d, x[ 1], S21); /* 21 */
        d = GG (d, a, b, c, x[ 5], S22); /* 22 */
        c = GG (c, d, a, b, x[ 9], S23); /* 23 */
        b = GG (b, c, d, a, x[13], S24); /* 24 */
        a = GG (a, b, c, d, x[ 2], S21); /* 25 */
        d = GG (d, a, b, c, x[ 6], S22); /* 26 */
        c = GG (c, d, a, b, x[10], S23); /* 27 */
        b = GG (b, c, d, a, x[14], S24); /* 28 */
        a = GG (a, b, c, d, x[ 3], S21); /* 29 */
        d = GG (d, a, b, c, x[ 7], S22); /* 30 */
        c = GG (c, d, a, b, x[11], S23); /* 31 */
        b = GG (b, c, d, a, x[15], S24); /* 32 */

        /* Round 3 */
        a = HH (a, b, c, d, x[ 0], S31); /* 33 */
        d = HH (d, a, b, c, x[ 8], S32); /* 34 */
        c = HH (c, d, a, b, x[ 4], S33); /* 35 */
        b = HH (b, c, d, a, x[12], S34); /* 36 */
        a = HH (a, b, c, d, x[ 2], S31); /* 37 */
        d = HH (d, a, b, c, x[10], S32); /* 38 */
        c = HH (c, d, a, b, x[ 6], S33); /* 39 */
        b = HH (b, c, d, a, x[14], S34); /* 40 */
        a = HH (a, b, c, d, x[ 1], S31); /* 41 */
        d = HH (d, a, b, c, x[ 9], S32); /* 42 */
        c = HH (c, d, a, b, x[ 5], S33); /* 43 */
        b = HH (b, c, d, a, x[13], S34); /* 44 */
        a = HH (a, b, c, d, x[ 3], S31); /* 45 */
        d = HH (d, a, b, c, x[11], S32); /* 46 */
        c = HH (c, d, a, b, x[ 7], S33); /* 47 */
        b = HH (b, c, d, a, x[15], S34); /* 48 */

        state[0] += a;
        state[1] += b;
        state[2] += c;
        state[3] += d;
    }

}
