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);
  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");
  }
  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;
}

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 ) ; 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" ) ; } 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 ; }
decrypts a message . < br / > see p1363 . 1 section 9 . 2 . 3 .
