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

package org.bouncycastle.crypto.agreement.jpake;

import org.bouncycastle.util.Arrays;
import org.bouncycastle.crypto.Mac;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.macs.HMac;
import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.CryptoException;
import org.bouncycastle.util.Strings;
import org.bouncycastle.util.BigIntegers;
import java.security.SecureRandom;
import java.math.BigInteger;

public class JPAKEUtil
{
    static final BigInteger ZERO;
    static final BigInteger ONE;
    
    public static BigInteger generateX1(final BigInteger bigInteger, final SecureRandom secureRandom) {
        return BigIntegers.createRandomInRange(JPAKEUtil.ZERO, bigInteger.subtract(JPAKEUtil.ONE), secureRandom);
    }
    
    public static BigInteger generateX2(final BigInteger bigInteger, final SecureRandom secureRandom) {
        return BigIntegers.createRandomInRange(JPAKEUtil.ONE, bigInteger.subtract(JPAKEUtil.ONE), secureRandom);
    }
    
    @Deprecated
    public static BigInteger calculateS(final char[] array) {
        return new BigInteger(1, Strings.toUTF8ByteArray(array));
    }
    
    public static BigInteger calculateS(final BigInteger m, final byte[] magnitude) throws CryptoException {
        final BigInteger mod = new BigInteger(1, magnitude).mod(m);
        if (mod.signum() == 0) {
            throw new CryptoException("MUST ensure s is not equal to 0 modulo q");
        }
        return mod;
    }
    
    public static BigInteger calculateS(final BigInteger bigInteger, final char[] array) throws CryptoException {
        return calculateS(bigInteger, Strings.toUTF8ByteArray(array));
    }
    
    public static BigInteger calculateGx(final BigInteger m, final BigInteger bigInteger, final BigInteger exponent) {
        return bigInteger.modPow(exponent, m);
    }
    
    public static BigInteger calculateGA(final BigInteger m, final BigInteger bigInteger, final BigInteger val, final BigInteger val2) {
        return bigInteger.multiply(val).multiply(val2).mod(m);
    }
    
    public static BigInteger calculateX2s(final BigInteger m, final BigInteger bigInteger, final BigInteger val) {
        return bigInteger.multiply(val).mod(m);
    }
    
    public static BigInteger calculateA(final BigInteger m, final BigInteger bigInteger, final BigInteger bigInteger2, final BigInteger exponent) {
        return bigInteger2.modPow(exponent, m);
    }
    
    public static BigInteger[] calculateZeroKnowledgeProof(final BigInteger m, final BigInteger i, final BigInteger bigInteger, final BigInteger bigInteger2, final BigInteger bigInteger3, final String s, final Digest digest, final SecureRandom secureRandom) {
        final BigInteger[] array = new BigInteger[2];
        final BigInteger randomInRange = BigIntegers.createRandomInRange(JPAKEUtil.ZERO, i.subtract(JPAKEUtil.ONE), secureRandom);
        final BigInteger modPow = bigInteger.modPow(randomInRange, m);
        final BigInteger calculateHashForZeroKnowledgeProof = calculateHashForZeroKnowledgeProof(bigInteger, modPow, bigInteger2, s, digest);
        array[0] = modPow;
        array[1] = randomInRange.subtract(bigInteger3.multiply(calculateHashForZeroKnowledgeProof)).mod(i);
        return array;
    }
    
    private static BigInteger calculateHashForZeroKnowledgeProof(final BigInteger bigInteger, final BigInteger bigInteger2, final BigInteger bigInteger3, final String s, final Digest digest) {
        digest.reset();
        updateDigestIncludingSize(digest, bigInteger);
        updateDigestIncludingSize(digest, bigInteger2);
        updateDigestIncludingSize(digest, bigInteger3);
        updateDigestIncludingSize(digest, s);
        final byte[] val = new byte[digest.getDigestSize()];
        digest.doFinal(val, 0);
        return new BigInteger(val);
    }
    
    public static void validateGx4(final BigInteger bigInteger) throws CryptoException {
        if (bigInteger.equals(JPAKEUtil.ONE)) {
            throw new CryptoException("g^x validation failed.  g^x should not be 1.");
        }
    }
    
    public static void validateGa(final BigInteger bigInteger) throws CryptoException {
        if (bigInteger.equals(JPAKEUtil.ONE)) {
            throw new CryptoException("ga is equal to 1.  It should not be.  The chances of this happening are on the order of 2^160 for a 160-bit q.  Try again.");
        }
    }
    
    public static void validateZeroKnowledgeProof(final BigInteger m, final BigInteger exponent, final BigInteger bigInteger, final BigInteger bigInteger2, final BigInteger[] array, final String s, final Digest digest) throws CryptoException {
        final BigInteger x = array[0];
        final BigInteger exponent2 = array[1];
        final BigInteger calculateHashForZeroKnowledgeProof = calculateHashForZeroKnowledgeProof(bigInteger, x, bigInteger2, s, digest);
        if (bigInteger2.signum() <= 0 || bigInteger2.compareTo(m) >= 0 || !bigInteger2.modPow(exponent, m).equals(JPAKEUtil.ONE) || !bigInteger.modPow(exponent2, m).multiply(bigInteger2.modPow(calculateHashForZeroKnowledgeProof, m)).mod(m).equals(x)) {
            throw new CryptoException("Zero-knowledge proof validation failed");
        }
    }
    
    public static BigInteger calculateKeyingMaterial(final BigInteger bigInteger, final BigInteger m, final BigInteger bigInteger2, final BigInteger exponent, final BigInteger val, final BigInteger val2) {
        return bigInteger2.modPow(exponent.multiply(val).negate().mod(m), bigInteger).multiply(val2).modPow(exponent, bigInteger);
    }
    
    public static void validateParticipantIdsDiffer(final String str, final String anObject) throws CryptoException {
        if (str.equals(anObject)) {
            throw new CryptoException("Both participants are using the same participantId (" + str + "). This is not allowed. Each participant must use a unique participantId.");
        }
    }
    
    public static void validateParticipantIdsEqual(final String str, final String s) throws CryptoException {
        if (!str.equals(s)) {
            throw new CryptoException("Received payload from incorrect partner (" + s + "). Expected to receive payload from " + str + ".");
        }
    }
    
    public static void validateNotNull(final Object o, final String str) {
        if (o == null) {
            throw new NullPointerException(str + " must not be null");
        }
    }
    
    public static BigInteger calculateMacTag(final String s, final String s2, final BigInteger bigInteger, final BigInteger bigInteger2, final BigInteger bigInteger3, final BigInteger bigInteger4, final BigInteger bigInteger5, final Digest digest) {
        final byte[] calculateMacKey = calculateMacKey(bigInteger5, digest);
        final HMac hMac = new HMac(digest);
        final byte[] val = new byte[hMac.getMacSize()];
        hMac.init(new KeyParameter(calculateMacKey));
        updateMac(hMac, "KC_1_U");
        updateMac(hMac, s);
        updateMac(hMac, s2);
        updateMac(hMac, bigInteger);
        updateMac(hMac, bigInteger2);
        updateMac(hMac, bigInteger3);
        updateMac(hMac, bigInteger4);
        hMac.doFinal(val, 0);
        Arrays.fill(calculateMacKey, (byte)0);
        return new BigInteger(val);
    }
    
    private static byte[] calculateMacKey(final BigInteger bigInteger, final Digest digest) {
        digest.reset();
        updateDigest(digest, bigInteger);
        updateDigest(digest, "JPAKE_KC");
        final byte[] array = new byte[digest.getDigestSize()];
        digest.doFinal(array, 0);
        return array;
    }
    
    public static void validateMacTag(final String s, final String s2, final BigInteger bigInteger, final BigInteger bigInteger2, final BigInteger bigInteger3, final BigInteger bigInteger4, final BigInteger bigInteger5, final Digest digest, final BigInteger x) throws CryptoException {
        if (!calculateMacTag(s2, s, bigInteger3, bigInteger4, bigInteger, bigInteger2, bigInteger5, digest).equals(x)) {
            throw new CryptoException("Partner MacTag validation failed. Therefore, the password, MAC, or digest algorithm of each participant does not match.");
        }
    }
    
    private static void updateDigest(final Digest digest, final BigInteger bigInteger) {
        final byte[] unsignedByteArray = BigIntegers.asUnsignedByteArray(bigInteger);
        digest.update(unsignedByteArray, 0, unsignedByteArray.length);
        Arrays.fill(unsignedByteArray, (byte)0);
    }
    
    private static void updateDigestIncludingSize(final Digest digest, final BigInteger bigInteger) {
        final byte[] unsignedByteArray = BigIntegers.asUnsignedByteArray(bigInteger);
        digest.update(intToByteArray(unsignedByteArray.length), 0, 4);
        digest.update(unsignedByteArray, 0, unsignedByteArray.length);
        Arrays.fill(unsignedByteArray, (byte)0);
    }
    
    private static void updateDigest(final Digest digest, final String s) {
        final byte[] utf8ByteArray = Strings.toUTF8ByteArray(s);
        digest.update(utf8ByteArray, 0, utf8ByteArray.length);
        Arrays.fill(utf8ByteArray, (byte)0);
    }
    
    private static void updateDigestIncludingSize(final Digest digest, final String s) {
        final byte[] utf8ByteArray = Strings.toUTF8ByteArray(s);
        digest.update(intToByteArray(utf8ByteArray.length), 0, 4);
        digest.update(utf8ByteArray, 0, utf8ByteArray.length);
        Arrays.fill(utf8ByteArray, (byte)0);
    }
    
    private static void updateMac(final Mac mac, final BigInteger bigInteger) {
        final byte[] unsignedByteArray = BigIntegers.asUnsignedByteArray(bigInteger);
        mac.update(unsignedByteArray, 0, unsignedByteArray.length);
        Arrays.fill(unsignedByteArray, (byte)0);
    }
    
    private static void updateMac(final Mac mac, final String s) {
        final byte[] utf8ByteArray = Strings.toUTF8ByteArray(s);
        mac.update(utf8ByteArray, 0, utf8ByteArray.length);
        Arrays.fill(utf8ByteArray, (byte)0);
    }
    
    private static byte[] intToByteArray(final int n) {
        return new byte[] { (byte)(n >>> 24), (byte)(n >>> 16), (byte)(n >>> 8), (byte)n };
    }
    
    static {
        ZERO = BigInteger.valueOf(0L);
        ONE = BigInteger.valueOf(1L);
    }
}
