// 
// Decompiled by Procyon v0.6.0
// 

package com.google.crypto.tink.subtle;

import java.util.Arrays;
import java.nio.ByteBuffer;
import java.security.GeneralSecurityException;
import java.security.MessageDigest;

public final class Bytes
{
    public static final boolean equal(final byte[] x, final byte[] y) {
        return MessageDigest.isEqual(x, y);
    }
    
    public static byte[] concat(final byte[]... chunks) throws GeneralSecurityException {
        int length = 0;
        for (final byte[] chunk : chunks) {
            if (length > Integer.MAX_VALUE - chunk.length) {
                throw new GeneralSecurityException("exceeded size limit");
            }
            length += chunk.length;
        }
        final byte[] res = new byte[length];
        int pos = 0;
        for (final byte[] chunk2 : chunks) {
            System.arraycopy(chunk2, 0, res, pos, chunk2.length);
            pos += chunk2.length;
        }
        return res;
    }
    
    public static final byte[] xor(final byte[] x, final int offsetX, final byte[] y, final int offsetY, final int len) {
        if (len < 0 || x.length - len < offsetX || y.length - len < offsetY) {
            throw new IllegalArgumentException("That combination of buffers, offsets and length to xor result in out-of-bond accesses.");
        }
        final byte[] res = new byte[len];
        for (int i = 0; i < len; ++i) {
            res[i] = (byte)(x[i + offsetX] ^ y[i + offsetY]);
        }
        return res;
    }
    
    public static final void xor(final ByteBuffer output, final ByteBuffer x, final ByteBuffer y, final int len) {
        if (len < 0 || x.remaining() < len || y.remaining() < len || output.remaining() < len) {
            throw new IllegalArgumentException("That combination of buffers, offsets and length to xor result in out-of-bond accesses.");
        }
        for (int i = 0; i < len; ++i) {
            output.put((byte)(x.get() ^ y.get()));
        }
    }
    
    public static final byte[] xor(final byte[] x, final byte[] y) {
        if (x.length != y.length) {
            throw new IllegalArgumentException("The lengths of x and y should match.");
        }
        return xor(x, 0, y, 0, x.length);
    }
    
    public static final byte[] xorEnd(final byte[] a, final byte[] b) {
        if (a.length < b.length) {
            throw new IllegalArgumentException("xorEnd requires a.length >= b.length");
        }
        final int paddingLength = a.length - b.length;
        final byte[] res = Arrays.copyOf(a, a.length);
        for (int i = 0; i < b.length; ++i) {
            final byte[] array = res;
            final int n = paddingLength + i;
            array[n] ^= b[i];
        }
        return res;
    }
    
    public static byte[] intToByteArray(final int capacity, final int value) {
        if (capacity > 4 || capacity < 0) {
            throw new IllegalArgumentException("capacity must be between 0 and 4");
        }
        if (value < 0 || (capacity < 4 && value >= 1 << 8 * capacity)) {
            throw new IllegalArgumentException("value too large");
        }
        final byte[] result = new byte[capacity];
        for (int i = 0; i < capacity; ++i) {
            result[i] = (byte)(value >> 8 * i & 0xFF);
        }
        return result;
    }
    
    public static int byteArrayToInt(final byte[] bytes) {
        return byteArrayToInt(bytes, bytes.length);
    }
    
    public static int byteArrayToInt(final byte[] bytes, final int length) {
        return byteArrayToInt(bytes, 0, length);
    }
    
    public static int byteArrayToInt(final byte[] bytes, final int offset, final int length) {
        if (length > 4 || length < 0) {
            throw new IllegalArgumentException("length must be between 0 and 4");
        }
        if (offset < 0 || offset + length > bytes.length) {
            throw new IllegalArgumentException("offset and length are out of bounds");
        }
        int value = 0;
        for (int i = 0; i < length; ++i) {
            value += (bytes[i + offset] & 0xFF) << i * 8;
        }
        return value;
    }
    
    private Bytes() {
    }
}
