/// <summary> /// Decrypt a cipher text /// </summary> /// /// <param name="Input">The cipher text</param> /// /// <returns>The plain text</returns> public byte[] Decrypt(byte[] Input) { if (m_isEncryption) { throw new CryptoAsymmetricException("FujisakiCipher:Decrypt", "The cipher is not initialized for decryption!", new ArgumentException()); } int c1Len = (m_N + 7) >> 3; int c2Len = Input.Length - c1Len; // split ciphertext (c1||c2) byte[][] c1c2 = ByteUtils.Split(Input, c1Len); byte[] c1 = c1c2[0]; byte[] c2 = c1c2[1]; // decrypt c1 ... GF2Vector hrmVec = GF2Vector.OS2VP(m_N, c1); GF2Vector[] decC1 = CCA2Primitives.Decrypt((MPKCPrivateKey)m_asmKey, hrmVec); byte[] rBytes = decC1[0].GetEncoded(); // ... and obtain error vector z GF2Vector z = decC1[1]; byte[] mBytes; // get PRNG object.. using (KDF2 sr0 = new KDF2(GetDigest(m_cprParams.Digest))) { // seed PRNG with r' sr0.Initialize(rBytes); // generate random sequence mBytes = new byte[c2Len]; sr0.Generate(mBytes); } // XOR with c2 to obtain m for (int i = 0; i < c2Len; i++) { mBytes[i] ^= c2[i]; } // compute H(r||m) byte[] rmBytes = ByteUtils.Concatenate(rBytes, mBytes); byte[] hrm = new byte[m_dgtEngine.DigestSize]; m_dgtEngine.BlockUpdate(rmBytes, 0, rmBytes.Length); m_dgtEngine.DoFinal(hrm, 0); // compute Conv(H(r||m)) hrmVec = CCA2Conversions.Encode(m_N, m_T, hrm); // check that Conv(H(m||r)) = z if (!hrmVec.Equals(z)) { throw new CryptoAsymmetricException("FujisakiCipher:Decrypt", "Bad Padding: invalid ciphertext!", new InvalidDataException()); } // return plaintext m return(mBytes); }
public byte[] Decrypt(byte[] Input) { int c1Len = (_N + 7) >> 3; int c2Len = Input.Length - c1Len; // split cipher text (c1||c2) byte[][] c1c2 = ByteUtils.Split(Input, c1Len); byte[] c1 = c1c2[0]; byte[] c2 = c1c2[1]; // decrypt c1 ... GF2Vector c1Vec = GF2Vector.OS2VP(_N, c1); GF2Vector[] c1Dec = CCA2Primitives.Decrypt((MPKCPrivateKey)_keyPair.PrivateKey, c1Vec); byte[] rPrimeBytes = c1Dec[0].GetEncoded(); // ... and obtain error vector z GF2Vector z = c1Dec[1]; byte[] mrBytes; // get PRNG object using (KDF2Drbg sr0 = new KDF2Drbg(GetDigest(_cipherParams.Digest))) { // seed PRNG with r' sr0.Initialize(rPrimeBytes); // generate random sequence mrBytes = new byte[c2Len]; sr0.Generate(mrBytes); } // XOR with c2 to obtain (m||r) for (int i = 0; i < c2Len; i++) { mrBytes[i] ^= c2[i]; } // compute H(m||r) _dgtEngine.BlockUpdate(mrBytes, 0, mrBytes.Length); byte[] hmr = new byte[_dgtEngine.DigestSize]; _dgtEngine.DoFinal(hmr, 0); // compute Conv(H(m||r)) c1Vec = CCA2Conversions.Encode(_N, _T, hmr); // check that Conv(H(m||r)) = z if (!c1Vec.Equals(z)) { throw new Exception("Bad Padding: Invalid ciphertext!");// Note: will throw (sometimes), but only on Pointcheval w/ small m/t? } // split (m||r) to obtain m int kDiv8 = _K >> 3; byte[][] mr = ByteUtils.Split(mrBytes, c2Len - kDiv8); // return plain text m return(mr[0]); }
/// <summary> /// Decrypt a cipher text /// </summary> /// /// <param name="Input">The cipher text</param> /// /// <returns>The plain text</returns> public byte[] Decrypt(byte[] Input) { int c1Len = (_N + 7) >> 3; int c2Len = Input.Length - c1Len; // split ciphertext (c1||c2) byte[][] c1c2 = ByteUtils.Split(Input, c1Len); byte[] c1 = c1c2[0]; byte[] c2 = c1c2[1]; // decrypt c1 ... GF2Vector hrmVec = GF2Vector.OS2VP(_N, c1); GF2Vector[] decC1 = CCA2Primitives.Decrypt((MPKCPrivateKey)_keyPair.PrivateKey, hrmVec); byte[] rBytes = decC1[0].GetEncoded(); // ... and obtain error vector z GF2Vector z = decC1[1]; byte[] mBytes; // get PRNG object.. using (KDF2Drbg sr0 = new KDF2Drbg(GetDigest(_cipherParams.Digest))) { // seed PRNG with r' sr0.Initialize(rBytes); // generate random sequence mBytes = new byte[c2Len]; sr0.Generate(mBytes); } // XOR with c2 to obtain m for (int i = 0; i < c2Len; i++) { mBytes[i] ^= c2[i]; } // compute H(r||m) byte[] rmBytes = ByteUtils.Concatenate(rBytes, mBytes); byte[] hrm = new byte[_dgtEngine.DigestSize]; _dgtEngine.BlockUpdate(rmBytes, 0, rmBytes.Length); _dgtEngine.DoFinal(hrm, 0); // compute Conv(H(r||m)) hrmVec = CCA2Conversions.Encode(_N, _T, hrm); // check that Conv(H(m||r)) = z if (!hrmVec.Equals(z)) { throw new Exception("Bad Padding: invalid ciphertext!"); } // return plaintext m return(mBytes); }
public byte[] Decrypt(byte[] Input) { if (m_isEncryption) { throw new CryptoAsymmetricException("PointchevalCipher:Decrypt", "The cipher is not initialized for decryption!", new ArgumentException()); } int c1Len = (m_N + 7) >> 3; int c2Len = Input.Length - c1Len; // split cipher text (c1||c2) byte[][] c1c2 = ByteUtils.Split(Input, c1Len); byte[] c1 = c1c2[0]; byte[] c2 = c1c2[1]; // decrypt c1 ... GF2Vector c1Vec = GF2Vector.OS2VP(m_N, c1); GF2Vector[] c1Dec = CCA2Primitives.Decrypt((MPKCPrivateKey)m_asmKey, c1Vec); byte[] rPrimeBytes = c1Dec[0].GetEncoded(); // ... and obtain error vector z GF2Vector z = c1Dec[1]; byte[] mrBytes; // get PRNG object using (KDF2 sr0 = new KDF2(GetDigest(m_cprParams.Digest))) { // seed PRNG with r' sr0.Initialize(rPrimeBytes); // generate random sequence mrBytes = new byte[c2Len]; sr0.Generate(mrBytes); } // XOR with c2 to obtain (m||r) for (int i = 0; i < c2Len; i++) { mrBytes[i] ^= c2[i]; } // compute H(m||r) m_dgtEngine.BlockUpdate(mrBytes, 0, mrBytes.Length); byte[] hmr = new byte[m_dgtEngine.DigestSize]; m_dgtEngine.DoFinal(hmr, 0); // compute Conv(H(m||r)) c1Vec = CCA2Conversions.Encode(m_N, m_T, hmr); // check that Conv(H(m||r)) = z if (!c1Vec.Equals(z)) { throw new CryptoAsymmetricException("PointchevalCipher:Decrypt", "Bad Padding: Invalid ciphertext!", new ArgumentException()); } // split (m||r) to obtain m int kDiv8 = m_K >> 3; byte[][] mr = ByteUtils.Split(mrBytes, c2Len - kDiv8); // return plain text m return(mr[0]); }