/*
 * $Id$
 * @author aakimov
 * @date   Jul 1, 2016 10:43:06 AM
 *
 * Copyright (C) 2016 Scytl Secure Electronic Voting SA
 *
 * All rights reserved.
 */
package com.scytl.math;

import java.math.BigInteger;
import java.util.List;

/**
 * Implementation of {@link MultiExponentiator} which uses native
 * implementation.
 * 
 * @author aakimov
 */
class NativeMultiExponentiator extends AbstractMultiExponentiator {
    private final byte[][] binaryBases;
    private final byte[] binaryModulus;

    /**
     * Constructor.
     * 
     * @param bases
     * @param modulus
     * @param maximumBitLengthOfExponent
     */
    public NativeMultiExponentiator(List<BigInteger> bases, BigInteger modulus,
            int maximumBitLengthOfExponent) {
        super(bases, modulus, maximumBitLengthOfExponent);
        binaryBases = toByteArrays(this.bases);
        binaryModulus = modulus.toByteArray();
    }

    private static native byte[] doExponentiateNative(byte[][] bases,
            byte[][] exponents, byte[] modulus);

    private static byte[][] toByteArrays(BigInteger[] numbers) {
        byte[][] arrays = new byte[numbers.length][];
        for (int i = 0; i < arrays.length; i++) {
            arrays[i] = numbers[i].toByteArray();
        }
        return arrays;
    }

    @Override
    protected BigInteger doExponentiate(BigInteger[] exponents) {
        byte[][] binaryExponents = toByteArrays(exponents);
        return new BigInteger(doExponentiateNative(binaryBases, binaryExponents,
                binaryModulus));
    }
}
