All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bouncycastle.pqc.crypto.ntruprime.SNTRUPrimeKeyPairGenerator Maven / Gradle / Ivy

Go to download

The Bouncy Castle Crypto package is a Java implementation of cryptographic algorithms. This jar contains JCE provider and lightweight API for the Bouncy Castle Cryptography APIs for Java 1.8 and later with debug enabled.

The newest version!
package org.bouncycastle.pqc.crypto.ntruprime;

import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator;
import org.bouncycastle.crypto.KeyGenerationParameters;
import org.bouncycastle.util.Arrays;

public class SNTRUPrimeKeyPairGenerator
    implements AsymmetricCipherKeyPairGenerator
{
    private SNTRUPrimeKeyGenerationParameters params;

    public SNTRUPrimeKeyGenerationParameters getParams()
    {
        return params;
    }

    /**
     * Initialize the Key Pair Generator.
     *
     * @param param the parameters the key pair is to be initialised with.
     */
    public void init(KeyGenerationParameters param)
    {
        this.params = (SNTRUPrimeKeyGenerationParameters) param;
    }

    /**
     * return an AsymmetricCipherKeyPair containing the generated keys.
     *
     * @return an AsymmetricCipherKeyPair containing the generated keys.
     */
    public AsymmetricCipherKeyPair generateKeyPair()
    {
        int p = params.getSntrupParams().getP();
        int q = params.getSntrupParams().getQ();
        int w = params.getSntrupParams().getW();

        /*
         * Generate Random Small Polynomial g from R/3 until it is invertible in R/3
         * Generate Inverse of Random Small Polynomial (1/g) in R/3
         */
        byte[] g = new byte[p];
        byte[] ginv = new byte[p];
        do Utils.getRandomSmallPolynomial(params.getRandom(), g);
            while (!Utils.isInvertiblePolynomialInR3(g, ginv, p));

        /*
         * Generate Random Short Polynomial from R/3 with weight w
         * Generate Inverse of Random Short Polynomial (1/3f) in R/q
         */
        byte[] f = new byte[p];
        Utils.getRandomShortPolynomial(params.getRandom(), f, p, w);

        short[] finv3 = new short[p];
        Utils.getOneThirdInverseInRQ(finv3, f, p, q);

        /*
         * Compute h = g/3f in R/q
         */
        short[] h = new short[p];
        Utils.multiplicationInRQ(h, finv3, g, p, q);

        /*
         * Public Key = Encode(h)
         */
        byte[] pk = new byte[params.getSntrupParams().getPublicKeyBytes()];
        Utils.getEncodedPolynomial(pk, h, p, q);

        SNTRUPrimePublicKeyParameters publicKey = new SNTRUPrimePublicKeyParameters(params.getSntrupParams(), pk);

        /*
         * Private Key = Encode(f) | Encode(1/g) | pk | Random rho | SHA-512(4|pk)
         */
        byte[] encF = new byte[(p + 3) / 4];
        Utils.getEncodedSmallPolynomial(encF, f, p);

        byte[] encGinv = new byte[(p + 3) / 4];
        Utils.getEncodedSmallPolynomial(encGinv, ginv, p);

        byte[] rho = new byte[(p + 3) / 4];
        params.getRandom().nextBytes(rho);

        byte[] prefix = {4};
        byte[] hash = Utils.getHashWithPrefix(prefix, pk);

        SNTRUPrimePrivateKeyParameters privateKey = new SNTRUPrimePrivateKeyParameters(params.getSntrupParams(), encF, encGinv,
                                                                                        pk, rho, Arrays.copyOfRange(hash, 0, hash.length / 2));

        return new AsymmetricCipherKeyPair(publicKey, privateKey);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy