/*
 * 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.cryptolib.primitives.ffc;

import java.math.BigInteger;

import com.scytl.cryptolib.api.exceptions.GeneralCryptoLibException;
import com.scytl.cryptolib.primitives.messagedigest.factory.MessageDigestFactory;
import com.scytl.cryptolib.securerandom.cryptoapi.CryptoAPIRandomBytes;

/**
 * Implementation of {@link PseudoRandomFactory}.
 */
class PseudoRandomFactoryImpl implements PseudoRandomFactory {
    private final MessageDigestFactory digestFactory;

    private final CryptoAPIRandomBytes random;

    /**
     * Constructor.
     * 
     * @param digestFactory
     * @param random
     */
    public PseudoRandomFactoryImpl(MessageDigestFactory digestFactory,
            CryptoAPIRandomBytes random) {
        this.digestFactory = digestFactory;
        this.random = random;
    }

    @Override
    public PseudoRandom newPseudoRandom(BigInteger seed) {
        return new PseudoRandomImpl(digestFactory.create(), seed);
    }

    @Override
    public PseudoRandom newPseudoRandom(int seedLength)
            throws GeneralCryptoLibException {
        return newPseudoRandom(newSeed(seedLength));
    }

    private BigInteger newSeed(int length)
            throws GeneralCryptoLibException {
        int byteLength = (length + Byte.SIZE - 1) / Byte.SIZE;
        int high = 1 << ((length - 1) % Byte.SIZE);
        int mask = high - 1;
        byte[] seed = random.nextRandom(byteLength);
        seed[0] = (byte) (high | (seed[0] & mask));
        return new BigInteger(1, seed);
    }
}
