Search in sources :

Example 1 with Polynomial

use of com.github.zhenwei.core.pqc.math.ntru.polynomial.Polynomial in project LinLong-Java by zhenwei1108.

the class NTRUEncryptionKeyPairGenerator method generateKeyPair.

/**
 * Generates a new encryption key pair.
 *
 * @return a key pair
 */
public AsymmetricCipherKeyPair generateKeyPair() {
    int N = params.N;
    int q = params.q;
    int df = params.df;
    int df1 = params.df1;
    int df2 = params.df2;
    int df3 = params.df3;
    int dg = params.dg;
    boolean fastFp = params.fastFp;
    boolean sparse = params.sparse;
    Polynomial t;
    IntegerPolynomial fq;
    IntegerPolynomial fp = null;
    // choose a random f that is invertible mod 3 and q
    while (true) {
        IntegerPolynomial f;
        // choose random t, calculate f and fp
        if (fastFp) {
            // if fastFp=true, f is always invertible mod 3
            t = params.polyType == NTRUParameters.TERNARY_POLYNOMIAL_TYPE_SIMPLE ? Util.generateRandomTernary(N, df, df, sparse, params.getRandom()) : ProductFormPolynomial.generateRandom(N, df1, df2, df3, df3, params.getRandom());
            f = t.toIntegerPolynomial();
            f.mult(3);
            f.coeffs[0] += 1;
        } else {
            t = params.polyType == NTRUParameters.TERNARY_POLYNOMIAL_TYPE_SIMPLE ? Util.generateRandomTernary(N, df, df - 1, sparse, params.getRandom()) : ProductFormPolynomial.generateRandom(N, df1, df2, df3, df3 - 1, params.getRandom());
            f = t.toIntegerPolynomial();
            fp = f.invertF3();
            if (fp == null) {
                continue;
            }
        }
        fq = f.invertFq(q);
        if (fq == null) {
            continue;
        }
        break;
    }
    // if fastFp=true, fp=1
    if (fastFp) {
        fp = new IntegerPolynomial(N);
        fp.coeffs[0] = 1;
    }
    // choose a random g that is invertible mod q
    DenseTernaryPolynomial g;
    while (true) {
        g = DenseTernaryPolynomial.generateRandom(N, dg, dg - 1, params.getRandom());
        if (g.invertFq(q) != null) {
            break;
        }
    }
    IntegerPolynomial h = g.mult(fq, q);
    h.mult3(q);
    h.ensurePositive(q);
    g.clear();
    fq.clear();
    NTRUEncryptionPrivateKeyParameters priv = new NTRUEncryptionPrivateKeyParameters(h, t, fp, params.getEncryptionParameters());
    NTRUEncryptionPublicKeyParameters pub = new NTRUEncryptionPublicKeyParameters(h, params.getEncryptionParameters());
    return new AsymmetricCipherKeyPair(pub, priv);
}
Also used : DenseTernaryPolynomial(com.github.zhenwei.core.pqc.math.ntru.polynomial.DenseTernaryPolynomial) ProductFormPolynomial(com.github.zhenwei.core.pqc.math.ntru.polynomial.ProductFormPolynomial) IntegerPolynomial(com.github.zhenwei.core.pqc.math.ntru.polynomial.IntegerPolynomial) Polynomial(com.github.zhenwei.core.pqc.math.ntru.polynomial.Polynomial) IntegerPolynomial(com.github.zhenwei.core.pqc.math.ntru.polynomial.IntegerPolynomial) DenseTernaryPolynomial(com.github.zhenwei.core.pqc.math.ntru.polynomial.DenseTernaryPolynomial) AsymmetricCipherKeyPair(com.github.zhenwei.core.crypto.AsymmetricCipherKeyPair)

Example 2 with Polynomial

use of com.github.zhenwei.core.pqc.math.ntru.polynomial.Polynomial in project LinLong-Java by zhenwei1108.

the class NTRUSigningKeyPairGenerator method generateBasis.

/**
 * Creates a NTRUSigner basis consisting of polynomials <code>f, g, F, G, h</code>.<br/> If
 * <code>KeyGenAlg=FLOAT</code>, the basis may not be valid and this method must be rerun if that
 * is the case.<br/>
 *
 * @see #generateBoundedBasis()
 */
private FGBasis generateBasis() {
    int N = params.N;
    int q = params.q;
    int d = params.d;
    int d1 = params.d1;
    int d2 = params.d2;
    int d3 = params.d3;
    int basisType = params.basisType;
    Polynomial f;
    IntegerPolynomial fInt;
    Polynomial g;
    IntegerPolynomial gInt;
    IntegerPolynomial fq;
    Resultant rf;
    Resultant rg;
    BigIntEuclidean r;
    int _2n1 = 2 * N + 1;
    boolean primeCheck = params.primeCheck;
    do {
        do {
            f = params.polyType == NTRUParameters.TERNARY_POLYNOMIAL_TYPE_SIMPLE ? DenseTernaryPolynomial.generateRandom(N, d + 1, d, CryptoServicesRegistrar.getSecureRandom()) : ProductFormPolynomial.generateRandom(N, d1, d2, d3 + 1, d3, CryptoServicesRegistrar.getSecureRandom());
            fInt = f.toIntegerPolynomial();
        } while (primeCheck && fInt.resultant(_2n1).res.equals(ZERO));
        fq = fInt.invertFq(q);
    } while (fq == null);
    rf = fInt.resultant();
    do {
        do {
            do {
                g = params.polyType == NTRUParameters.TERNARY_POLYNOMIAL_TYPE_SIMPLE ? DenseTernaryPolynomial.generateRandom(N, d + 1, d, CryptoServicesRegistrar.getSecureRandom()) : ProductFormPolynomial.generateRandom(N, d1, d2, d3 + 1, d3, CryptoServicesRegistrar.getSecureRandom());
                gInt = g.toIntegerPolynomial();
            } while (primeCheck && gInt.resultant(_2n1).res.equals(ZERO));
        } while (gInt.invertFq(q) == null);
        rg = gInt.resultant();
        r = BigIntEuclidean.calculate(rf.res, rg.res);
    } while (!r.gcd.equals(ONE));
    BigIntPolynomial A = (BigIntPolynomial) rf.rho.clone();
    A.mult(r.x.multiply(BigInteger.valueOf(q)));
    BigIntPolynomial B = (BigIntPolynomial) rg.rho.clone();
    B.mult(r.y.multiply(BigInteger.valueOf(-q)));
    BigIntPolynomial C;
    if (params.keyGenAlg == NTRUSigningKeyGenerationParameters.KEY_GEN_ALG_RESULTANT) {
        int[] fRevCoeffs = new int[N];
        int[] gRevCoeffs = new int[N];
        fRevCoeffs[0] = fInt.coeffs[0];
        gRevCoeffs[0] = gInt.coeffs[0];
        for (int i = 1; i < N; i++) {
            fRevCoeffs[i] = fInt.coeffs[N - i];
            gRevCoeffs[i] = gInt.coeffs[N - i];
        }
        IntegerPolynomial fRev = new IntegerPolynomial(fRevCoeffs);
        IntegerPolynomial gRev = new IntegerPolynomial(gRevCoeffs);
        IntegerPolynomial t = f.mult(fRev);
        t.add(g.mult(gRev));
        Resultant rt = t.resultant();
        C = fRev.mult(// fRev.mult(B) is actually faster than new SparseTernaryPolynomial(fRev).mult(B), possibly due to cache locality?
        B);
        C.add(gRev.mult(A));
        C = C.mult(rt.rho);
        C.div(rt.res);
    } else {
        // KeyGenAlg.FLOAT
        // calculate ceil(log10(N))
        int log10N = 0;
        for (int i = 1; i < N; i *= 10) {
            log10N++;
        }
        // * Cdec needs to be accurate to 1 decimal place so it can be correctly rounded;
        // * fInv loses up to (#digits of longest coeff of B) places in fInv.mult(B);
        // * multiplying fInv by B also multiplies the rounding error by a factor of N;
        // so make #decimal places of fInv the sum of the above.
        BigDecimalPolynomial fInv = rf.rho.div(new BigDecimal(rf.res), B.getMaxCoeffLength() + 1 + log10N);
        BigDecimalPolynomial gInv = rg.rho.div(new BigDecimal(rg.res), A.getMaxCoeffLength() + 1 + log10N);
        BigDecimalPolynomial Cdec = fInv.mult(B);
        Cdec.add(gInv.mult(A));
        Cdec.halve();
        C = Cdec.round();
    }
    BigIntPolynomial F = (BigIntPolynomial) B.clone();
    F.sub(f.mult(C));
    BigIntPolynomial G = (BigIntPolynomial) A.clone();
    G.sub(g.mult(C));
    IntegerPolynomial FInt = new IntegerPolynomial(F);
    IntegerPolynomial GInt = new IntegerPolynomial(G);
    minimizeFG(fInt, gInt, FInt, GInt, N);
    Polynomial fPrime;
    IntegerPolynomial h;
    if (basisType == NTRUSigningKeyGenerationParameters.BASIS_TYPE_STANDARD) {
        fPrime = FInt;
        h = g.mult(fq, q);
    } else {
        fPrime = g;
        h = FInt.mult(fq, q);
    }
    h.modPositive(q);
    return new FGBasis(f, fPrime, h, FInt, GInt, params);
}
Also used : BigDecimalPolynomial(com.github.zhenwei.core.pqc.math.ntru.polynomial.BigDecimalPolynomial) DenseTernaryPolynomial(com.github.zhenwei.core.pqc.math.ntru.polynomial.DenseTernaryPolynomial) ProductFormPolynomial(com.github.zhenwei.core.pqc.math.ntru.polynomial.ProductFormPolynomial) BigIntPolynomial(com.github.zhenwei.core.pqc.math.ntru.polynomial.BigIntPolynomial) IntegerPolynomial(com.github.zhenwei.core.pqc.math.ntru.polynomial.IntegerPolynomial) Polynomial(com.github.zhenwei.core.pqc.math.ntru.polynomial.Polynomial) BigDecimalPolynomial(com.github.zhenwei.core.pqc.math.ntru.polynomial.BigDecimalPolynomial) Resultant(com.github.zhenwei.core.pqc.math.ntru.polynomial.Resultant) BigIntEuclidean(com.github.zhenwei.core.pqc.math.ntru.euclid.BigIntEuclidean) IntegerPolynomial(com.github.zhenwei.core.pqc.math.ntru.polynomial.IntegerPolynomial) BigIntPolynomial(com.github.zhenwei.core.pqc.math.ntru.polynomial.BigIntPolynomial) BigDecimal(java.math.BigDecimal)

Example 3 with Polynomial

use of com.github.zhenwei.core.pqc.math.ntru.polynomial.Polynomial in project LinLong-Java by zhenwei1108.

the class NTRUEngine method encrypt.

/**
 * Encrypts a message.<br/> See P1363.1 section 9.2.2.
 *
 * @param m      The message to encrypt
 * @param pubKey the public key to encrypt the message with
 * @return the encrypted message
 */
private byte[] encrypt(byte[] m, NTRUEncryptionPublicKeyParameters pubKey) {
    IntegerPolynomial pub = pubKey.h;
    int N = params.N;
    int q = params.q;
    int maxLenBytes = params.maxMsgLenBytes;
    int db = params.db;
    int bufferLenBits = params.bufferLenBits;
    int dm0 = params.dm0;
    int pkLen = params.pkLen;
    int minCallsMask = params.minCallsMask;
    boolean hashSeed = params.hashSeed;
    byte[] oid = params.oid;
    int l = m.length;
    if (maxLenBytes > 255) {
        throw new IllegalArgumentException("llen values bigger than 1 are not supported");
    }
    if (l > maxLenBytes) {
        throw new DataLengthException("Message too long: " + l + ">" + maxLenBytes);
    }
    while (true) {
        // M = b|octL|m|p0
        byte[] b = new byte[db / 8];
        random.nextBytes(b);
        byte[] p0 = new byte[maxLenBytes + 1 - l];
        byte[] M = new byte[bufferLenBits / 8];
        System.arraycopy(b, 0, M, 0, b.length);
        M[b.length] = (byte) l;
        System.arraycopy(m, 0, M, b.length + 1, m.length);
        System.arraycopy(p0, 0, M, b.length + 1 + m.length, p0.length);
        IntegerPolynomial mTrin = IntegerPolynomial.fromBinary3Sves(M, N);
        // sData = OID|m|b|hTrunc
        byte[] bh = pub.toBinary(q);
        byte[] hTrunc = copyOf(bh, pkLen / 8);
        byte[] sData = buildSData(oid, m, l, b, hTrunc);
        Polynomial r = generateBlindingPoly(sData, M);
        IntegerPolynomial R = r.mult(pub, q);
        IntegerPolynomial R4 = (IntegerPolynomial) R.clone();
        R4.modPositive(4);
        byte[] oR4 = R4.toBinary(4);
        IntegerPolynomial mask = MGF(oR4, N, minCallsMask, hashSeed);
        mTrin.add(mask);
        mTrin.mod3();
        if (mTrin.count(-1) < dm0) {
            continue;
        }
        if (mTrin.count(0) < dm0) {
            continue;
        }
        if (mTrin.count(1) < dm0) {
            continue;
        }
        R.add(mTrin, q);
        R.ensurePositive(q);
        return R.toBinary(q);
    }
}
Also used : DenseTernaryPolynomial(com.github.zhenwei.core.pqc.math.ntru.polynomial.DenseTernaryPolynomial) ProductFormPolynomial(com.github.zhenwei.core.pqc.math.ntru.polynomial.ProductFormPolynomial) TernaryPolynomial(com.github.zhenwei.core.pqc.math.ntru.polynomial.TernaryPolynomial) IntegerPolynomial(com.github.zhenwei.core.pqc.math.ntru.polynomial.IntegerPolynomial) SparseTernaryPolynomial(com.github.zhenwei.core.pqc.math.ntru.polynomial.SparseTernaryPolynomial) Polynomial(com.github.zhenwei.core.pqc.math.ntru.polynomial.Polynomial) IntegerPolynomial(com.github.zhenwei.core.pqc.math.ntru.polynomial.IntegerPolynomial) DataLengthException(com.github.zhenwei.core.crypto.DataLengthException)

Example 4 with Polynomial

use of com.github.zhenwei.core.pqc.math.ntru.polynomial.Polynomial in project LinLong-Java by zhenwei1108.

the class NTRUEngine method decrypt.

/**
 * Decrypts a message.<br/> See P1363.1 section 9.2.3.
 *
 * @param data    The message to decrypt
 * @param privKey the corresponding private key
 * @return the decrypted message
 * @throws InvalidCipherTextException if  the encrypted data is invalid, or <code>maxLenBytes</code>
 *                                    is greater than 255
 */
private byte[] decrypt(byte[] data, NTRUEncryptionPrivateKeyParameters privKey) throws InvalidCipherTextException {
    Polynomial priv_t = privKey.t;
    IntegerPolynomial priv_fp = privKey.fp;
    IntegerPolynomial pub = privKey.h;
    int N = params.N;
    int q = params.q;
    int db = params.db;
    int maxMsgLenBytes = params.maxMsgLenBytes;
    int dm0 = params.dm0;
    int pkLen = params.pkLen;
    int minCallsMask = params.minCallsMask;
    boolean hashSeed = params.hashSeed;
    byte[] oid = params.oid;
    if (maxMsgLenBytes > 255) {
        throw new DataLengthException("maxMsgLenBytes values bigger than 255 are not supported");
    }
    int bLen = db / 8;
    IntegerPolynomial e = IntegerPolynomial.fromBinary(data, N, q);
    IntegerPolynomial ci = decrypt(e, priv_t, priv_fp);
    if (ci.count(-1) < dm0) {
        throw new InvalidCipherTextException("Less than dm0 coefficients equal -1");
    }
    if (ci.count(0) < dm0) {
        throw new InvalidCipherTextException("Less than dm0 coefficients equal 0");
    }
    if (ci.count(1) < dm0) {
        throw new InvalidCipherTextException("Less than dm0 coefficients equal 1");
    }
    IntegerPolynomial cR = (IntegerPolynomial) e.clone();
    cR.sub(ci);
    cR.modPositive(q);
    IntegerPolynomial cR4 = (IntegerPolynomial) cR.clone();
    cR4.modPositive(4);
    byte[] coR4 = cR4.toBinary(4);
    IntegerPolynomial mask = MGF(coR4, N, minCallsMask, hashSeed);
    IntegerPolynomial cMTrin = ci;
    cMTrin.sub(mask);
    cMTrin.mod3();
    byte[] cM = cMTrin.toBinary3Sves();
    byte[] cb = new byte[bLen];
    System.arraycopy(cM, 0, cb, 0, bLen);
    // llen=1, so read one byte
    int cl = cM[bLen] & 0xFF;
    if (cl > maxMsgLenBytes) {
        throw new InvalidCipherTextException("Message too long: " + cl + ">" + maxMsgLenBytes);
    }
    byte[] cm = new byte[cl];
    System.arraycopy(cM, bLen + 1, cm, 0, cl);
    byte[] p0 = new byte[cM.length - (bLen + 1 + cl)];
    System.arraycopy(cM, bLen + 1 + cl, p0, 0, p0.length);
    if (!Arrays.constantTimeAreEqual(p0, new byte[p0.length])) {
        throw new InvalidCipherTextException("The message is not followed by zeroes");
    }
    // sData = OID|m|b|hTrunc
    byte[] bh = pub.toBinary(q);
    byte[] hTrunc = copyOf(bh, pkLen / 8);
    byte[] sData = buildSData(oid, cm, cl, cb, hTrunc);
    Polynomial cr = generateBlindingPoly(sData, cm);
    IntegerPolynomial cRPrime = cr.mult(pub);
    cRPrime.modPositive(q);
    if (!cRPrime.equals(cR)) {
        throw new InvalidCipherTextException("Invalid message encoding");
    }
    return cm;
}
Also used : DenseTernaryPolynomial(com.github.zhenwei.core.pqc.math.ntru.polynomial.DenseTernaryPolynomial) ProductFormPolynomial(com.github.zhenwei.core.pqc.math.ntru.polynomial.ProductFormPolynomial) TernaryPolynomial(com.github.zhenwei.core.pqc.math.ntru.polynomial.TernaryPolynomial) IntegerPolynomial(com.github.zhenwei.core.pqc.math.ntru.polynomial.IntegerPolynomial) SparseTernaryPolynomial(com.github.zhenwei.core.pqc.math.ntru.polynomial.SparseTernaryPolynomial) Polynomial(com.github.zhenwei.core.pqc.math.ntru.polynomial.Polynomial) InvalidCipherTextException(com.github.zhenwei.core.crypto.InvalidCipherTextException) IntegerPolynomial(com.github.zhenwei.core.pqc.math.ntru.polynomial.IntegerPolynomial) DataLengthException(com.github.zhenwei.core.crypto.DataLengthException)

Example 5 with Polynomial

use of com.github.zhenwei.core.pqc.math.ntru.polynomial.Polynomial in project LinLong-Java by zhenwei1108.

the class NTRUSigner method sign.

private IntegerPolynomial sign(IntegerPolynomial i, NTRUSigningPrivateKeyParameters kp) {
    int N = params.N;
    int q = params.q;
    int perturbationBases = params.B;
    NTRUSigningPrivateKeyParameters kPriv = kp;
    NTRUSigningPublicKeyParameters kPub = kp.getPublicKey();
    IntegerPolynomial s = new IntegerPolynomial(N);
    int iLoop = perturbationBases;
    while (iLoop >= 1) {
        Polynomial f = kPriv.getBasis(iLoop).f;
        Polynomial fPrime = kPriv.getBasis(iLoop).fPrime;
        IntegerPolynomial y = f.mult(i);
        y.div(q);
        y = fPrime.mult(y);
        IntegerPolynomial x = fPrime.mult(i);
        x.div(q);
        x = f.mult(x);
        IntegerPolynomial si = y;
        si.sub(x);
        s.add(si);
        IntegerPolynomial hi = (IntegerPolynomial) kPriv.getBasis(iLoop).h.clone();
        if (iLoop > 1) {
            hi.sub(kPriv.getBasis(iLoop - 1).h);
        } else {
            hi.sub(kPub.h);
        }
        i = si.mult(hi, q);
        iLoop--;
    }
    Polynomial f = kPriv.getBasis(0).f;
    Polynomial fPrime = kPriv.getBasis(0).fPrime;
    IntegerPolynomial y = f.mult(i);
    y.div(q);
    y = fPrime.mult(y);
    IntegerPolynomial x = fPrime.mult(i);
    x.div(q);
    x = f.mult(x);
    y.sub(x);
    s.add(y);
    s.modPositive(q);
    return s;
}
Also used : IntegerPolynomial(com.github.zhenwei.core.pqc.math.ntru.polynomial.IntegerPolynomial) Polynomial(com.github.zhenwei.core.pqc.math.ntru.polynomial.Polynomial) IntegerPolynomial(com.github.zhenwei.core.pqc.math.ntru.polynomial.IntegerPolynomial)

Aggregations

IntegerPolynomial (com.github.zhenwei.core.pqc.math.ntru.polynomial.IntegerPolynomial)5 Polynomial (com.github.zhenwei.core.pqc.math.ntru.polynomial.Polynomial)5 DenseTernaryPolynomial (com.github.zhenwei.core.pqc.math.ntru.polynomial.DenseTernaryPolynomial)4 ProductFormPolynomial (com.github.zhenwei.core.pqc.math.ntru.polynomial.ProductFormPolynomial)4 DataLengthException (com.github.zhenwei.core.crypto.DataLengthException)2 SparseTernaryPolynomial (com.github.zhenwei.core.pqc.math.ntru.polynomial.SparseTernaryPolynomial)2 TernaryPolynomial (com.github.zhenwei.core.pqc.math.ntru.polynomial.TernaryPolynomial)2 AsymmetricCipherKeyPair (com.github.zhenwei.core.crypto.AsymmetricCipherKeyPair)1 InvalidCipherTextException (com.github.zhenwei.core.crypto.InvalidCipherTextException)1 BigIntEuclidean (com.github.zhenwei.core.pqc.math.ntru.euclid.BigIntEuclidean)1 BigDecimalPolynomial (com.github.zhenwei.core.pqc.math.ntru.polynomial.BigDecimalPolynomial)1 BigIntPolynomial (com.github.zhenwei.core.pqc.math.ntru.polynomial.BigIntPolynomial)1 Resultant (com.github.zhenwei.core.pqc.math.ntru.polynomial.Resultant)1 BigDecimal (java.math.BigDecimal)1