/*
 * 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.encryption.params.generation;

import com.scytl.cryptolib.api.primitives.PrimitivesServiceAPI;
import com.scytl.cryptolib.elgamal.bean.ElGamalEncryptionParameters;
import com.scytl.cryptolib.elgamal.encrytionparams.ElGamalEncryptionParamsGenerator;
import com.scytl.cryptolib.elgamal.encrytionparams.QuadResParamsGenerator;
import com.scytl.cryptolib.securerandom.cryptoapi.CryptoAPIRandomBytes;
import com.scytl.cryptolib.securerandom.cryptoapi.CryptoAPIRandomInteger;

/**
 * Allows the generation of ElGamal encryption parameters.
 * <P>
 * Provides methods for generating two "types" of encryption parameters, these are:
 * <ul>
 * <li>ZpSubGroup encryption parameters.
 * <li>Quadratic residue encryption parameters.
 * </ul>
 * In both cases, the output is represented by the same structure, and both contain the same parameters. The only
 * difference between them is in the algorithm for generating them, and in the relationships between the generated
 * parameters.
 */
public final class UniversalElGamalEncryptionParamsGenerator {

    private static final int CERTAINTY_LEVEL = 90;

    private final PrimitivesServiceAPI primitivesService;

    private final CryptoAPIRandomInteger cryptoRandomInteger;

    private final CryptoAPIRandomBytes cryptoRandomBytes;

    public UniversalElGamalEncryptionParamsGenerator(PrimitivesServiceAPI primitivesService) {

        this.primitivesService = primitivesService;
        this.cryptoRandomInteger = this.primitivesService.getCryptoRandomInteger();
        this.cryptoRandomBytes = this.primitivesService.getCryptoRandomBytes();
    }

    public ElGamalEncryptionParameters generateZpSubGroupEncryptionParameters(final int pBits, final int qBits) {

        ElGamalEncryptionParamsGenerator elGamalEncryptionParamsGenerator =
            new ElGamalEncryptionParamsGenerator(pBits, qBits, CERTAINTY_LEVEL, cryptoRandomBytes);

        return elGamalEncryptionParamsGenerator.generate();
    }

    public ElGamalEncryptionParameters generateQuadraticResidueEncryptionParameters(final int pBits) {

        QuadResParamsGenerator quadResParamsGenerator =
            new QuadResParamsGenerator(pBits, CERTAINTY_LEVEL, cryptoRandomInteger);

        return quadResParamsGenerator.generate();
    }
}
