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

package org.bouncycastle.crypto.threshold;

import org.bouncycastle.util.Arrays;
import java.io.IOException;
import java.security.SecureRandom;

public class ShamirSecretSplitter implements SecretSplitter
{
    private final Polynomial poly;
    protected int l;
    protected SecureRandom random;
    
    public ShamirSecretSplitter(final Algorithm algorithm, final Mode mode, final int l, final SecureRandom random) {
        if (l < 0 || l > 65534) {
            throw new IllegalArgumentException("Invalid input: l ranges from 0 to 65534 (2^16-2) bytes.");
        }
        this.poly = Polynomial.newInstance(algorithm, mode);
        this.l = l;
        this.random = random;
    }
    
    @Override
    public ShamirSplitSecret split(final int n, final int n2) {
        final byte[][] initP = this.initP(n, n2);
        final byte[][] array = new byte[n][this.l];
        final ShamirSplitSecretShare[] array2 = new ShamirSplitSecretShare[this.l];
        for (int i = 0; i < n; ++i) {
            this.random.nextBytes(array[i]);
        }
        for (int j = 0; j < initP.length; ++j) {
            array2[j] = new ShamirSplitSecretShare(this.poly.gfVecMul(initP[j], array), j + 1);
        }
        return new ShamirSplitSecret(this.poly, array2);
    }
    
    @Override
    public ShamirSplitSecret splitAround(final SecretShare secretShare, final int n, final int n2) throws IOException {
        final byte[][] initP = this.initP(n, n2);
        final byte[][] array = new byte[n][this.l];
        final ShamirSplitSecretShare[] array2 = new ShamirSplitSecretShare[this.l];
        final byte[] encoded = secretShare.getEncoded();
        array2[0] = new ShamirSplitSecretShare(encoded, 1);
        for (int i = 0; i < n; ++i) {
            this.random.nextBytes(array[i]);
        }
        for (int j = 0; j < this.l; ++j) {
            byte b = array[1][j];
            for (int k = 2; k < n; ++k) {
                b ^= array[k][j];
            }
            array[0][j] = (byte)(b ^ encoded[j]);
        }
        for (int l = 1; l < initP.length; ++l) {
            array2[l] = new ShamirSplitSecretShare(this.poly.gfVecMul(initP[l], array), l + 1);
        }
        return new ShamirSplitSecret(this.poly, array2);
    }
    
    @Override
    public ShamirSplitSecret resplit(final byte[] array, final int n, final int n2) {
        final byte[][] initP = this.initP(n, n2);
        final byte[][] array2 = new byte[n][this.l];
        final ShamirSplitSecretShare[] array3 = new ShamirSplitSecretShare[this.l];
        array2[0] = Arrays.clone(array);
        for (int i = 1; i < n; ++i) {
            this.random.nextBytes(array2[i]);
        }
        for (int j = 0; j < initP.length; ++j) {
            array3[j] = new ShamirSplitSecretShare(this.poly.gfVecMul(initP[j], array2), j + 1);
        }
        return new ShamirSplitSecret(this.poly, array3);
    }
    
    private byte[][] initP(final int n, final int n2) {
        if (n < 1 || n > 255) {
            throw new IllegalArgumentException("Invalid input: m must be less than 256 and positive.");
        }
        if (n2 < n || n2 > 255) {
            throw new IllegalArgumentException("Invalid input: n must be less than 256 and greater than or equal to n.");
        }
        final byte[][] array = new byte[n2][n];
        for (int i = 0; i < n2; ++i) {
            for (int j = 0; j < n; ++j) {
                array[i][j] = this.poly.gfPow((byte)(i + 1), (byte)j);
            }
        }
        return array;
    }
    
    public enum Algorithm
    {
        AES, 
        RSA;
    }
    
    public enum Mode
    {
        Native, 
        Table;
    }
}
