/*
 * Copyright 2018 Scytl Secure Electronic Voting SA
 *
 * All rights reserved
 *
 * See our extended copyright notice in *file 'Copyright.txt' which is part of this source code package
 */
package com.scytl.products.ov.mixnet.commons.concurrent.processor;

import com.scytl.cryptolib.api.exceptions.CryptoLibException;
import com.scytl.cryptolib.api.exceptions.GeneralCryptoLibException;
import com.scytl.cryptolib.elgamal.cryptoapi.Ciphertext;
import com.scytl.cryptolib.mathematical.groups.impl.Exponent;
import com.scytl.products.ov.mixnet.commons.concurrent.ParallelProcessAction;
import com.scytl.products.ov.mixnet.commons.homomorphic.Cryptosystem;
import com.scytl.products.ov.mixnet.commons.homomorphic.Randomness;
import com.scytl.products.ov.mixnet.commons.tools.LoopTools.Range;

/**
 * Base case to be parallelized using {@code LoopParallelizerAction}
 */
public class EncryptRaisingToRandomProcessor implements ParallelProcessAction {

    private final Ciphertext[] cE;

    private final Exponent[] b;

    private final Randomness[] tau;

    private final Cryptosystem cryptosystem;

    public EncryptRaisingToRandomProcessor(final Ciphertext[] cE, final Exponent[] b, final Randomness[] tau,
            final Cryptosystem cryptosystem) {
    	this.cE = cE;
    	this.b = b;
    	this.tau = tau;
    	this.cryptosystem = cryptosystem;
    }

    /**
     * @see com.scytl.products.ov.mixnet.commons.concurrent.ParallelProcessAction#run(com.scytl.products.ov.mixnet.commons
     *      .tools.LoopTools.Range)
     */
    @Override
    public void run(final Range range) {

        for (int i = range.getStart(), rangeEnd = range.getEnd(); i < rangeEnd; i++) {

            try {
                cE[i] = cE[i].multiply(cryptosystem.encryptRaisingToRandom(b[i], tau[i]));
            } catch (GeneralCryptoLibException e) {
                throw new CryptoLibException(e);
            }
        }
    }
}
