public static BufLen Decrypt(BufLen data, I2PPrivateKey pkey, bool zeropad) { if (data == null || (zeropad && data.Length != 514)) { throw new ArgumentException("ElGamal padded data to decrypt must be exactly 514 bytes!"); } if (!zeropad && data.Length != 512) { throw new ArgumentException("ElGamal data to decrypt must be exactly 512 bytes!"); } var x = I2PConstants.ElGamalP.Subtract(pkey.ToBigInteger()).Subtract(BigInteger.One); BigInteger a, b; var reader = new BufRefLen(data); if (zeropad) { reader.Seek(1); a = reader.ReadBigInteger(256); reader.Seek(1); b = reader.ReadBigInteger(256); } else { a = reader.ReadBigInteger(256); b = reader.ReadBigInteger(256); } var m2 = b.Multiply(a.ModPow(x, I2PConstants.ElGamalP)); var m1 = m2.Mod(I2PConstants.ElGamalP); var m = m1.ToByteArray(255); var hash = I2PHashSHA256.GetHash(m, 33, 222); if (!BufUtils.Equal(m, 1, hash, 0, 32)) { throw new HashCheckFailException(); } return(new BufLen(m, 33, 222)); }
public static BufLen Decrypt(BufLen data, I2PPrivateKey pkey, bool zeropad) { if (data == null || zeropad && data.Length != EncryptedPaddedLength) { throw new ArgumentException($"ElGamal padded data to decrypt must be exactly {EncryptedPaddedLength} bytes!"); } if (!zeropad && data.Length != EncryptedShortLength) { throw new ArgumentException($"ElGamal data to decrypt must be exactly {EncryptedShortLength} bytes!"); } var x = I2PConstants.ElGamalPMinusOne.Subtract(pkey.ToBigInteger()); var reader = new BufRefLen(data); var readlen = zeropad ? EncryptedPaddedLength / 2 : EncryptedShortLength / 2; var a = reader.ReadBigInteger(readlen); var b = reader.ReadBigInteger(readlen); var m2 = b.Multiply(a.ModPow(x, I2PConstants.ElGamalP)); var m1 = m2.Mod(I2PConstants.ElGamalP); var m = m1.ToByteArrayUnsigned(); var payload = new BufLen(m, 33, ClearTextLength); var hash = I2PHashSHA256.GetHash(payload); if (!BufUtils.Equal(m, 1, hash, 0, 32)) { throw new HashCheckFailException(); } return(payload); }