void ComputeIccContext()
        {
            var issuerModulusLength = new BigInteger(issuerPrivateKey.Modulus, 16).BitLength / 8;
            var iccPublicKey        = certificateData.IccPrivateKey.GetPublicKey();
            var iccModulusLength    = new BigInteger(iccPublicKey.Modulus, 16).BitLength / 8;

            var iccPublicKeyCertificate = new IccPublicKeyCertificate
            {
                HashAlgorithmIndicator      = certificateData.HashAlgorithmIndicator.FromHexa().First(),
                ApplicationPan              = certificateData.ApplicationPan.FromHexa(),
                CertificateExpirationDate   = certificateData.ExpirationDate.FromHexa(),
                CertificateSerialNumber     = certificateData.SerialNumber.FromHexa(),
                PublicKeyAlgorithmIndicator = certificateData.PublicKeyAlgorithmIndicator.FromHexa().First(),
                IccPublicKey = iccPublicKey
            };

            IccContext = new EmvIccContext()
            {
                ApplicationPan = certificateData.ApplicationPan,
                IccPrivateKey  = certificateData.IccPrivateKey
            };

            // 9F46 ICC Public Key Certificate (Nca)
            IccContext.IccPublicKeyCertificate = iccPublicKeyCertificate.GenerateCertificate(issuerPrivateKey.GetPrivateKey()).ToHexa();

            // 9F48 ICC Public Key Remainder (Ni-Nca+42)
            if (iccModulusLength > issuerModulusLength - 42)
            {
                IccContext.IccPublicKeyRemainder = iccPublicKey.Modulus.FromHexa().Skip(issuerModulusLength - 42).ToArray().ToHexa();
            }

            // 9F47 ICC Public Key Exponent (1 or 3)
            IccContext.IccPrivateKey.PublicExponent = iccPublicKey.Exponent.FromHexa().ToHexa();
        }
        public static byte[] BuildPinVerifyData(KernelDatabaseBase database, CAPublicKeyCertificate caPublicKey, byte[] pinBlock, byte[] challenge)
        {
            IssuerPublicKeyCertificate ipk = IssuerPublicKeyCertificate.BuildAndValidatePublicKey(database, caPublicKey.Modulus, caPublicKey.Exponent);

            if (ipk == null)
            {
                return(null);
            }

            int keyLength = 0;
            PublicKeyCertificate iccKey = IccPinKeyCertificate.BuildAndValidatePublicKey(database, ipk.Modulus, ipk.Exponent);

            if (iccKey == null)
            {
                iccKey = IccPublicKeyCertificate.BuildAndValidatePublicKey(database, database.StaticDataToBeAuthenticated, ipk.Modulus, ipk.Exponent);
                if (iccKey == null)
                {
                    return(null);
                }

                keyLength = ((IccPublicKeyCertificate)iccKey).ICCPublicKeyLength;
            }
            else
            {
                keyLength = ((IccPinKeyCertificate)iccKey).ICCPinKeyLength;
            }

            int paddingLength = keyLength - 17;

            byte[] padding = new byte[paddingLength];
            byte[] pinData = Formatting.ConcatArrays(new byte[] { 0x7F }, pinBlock, challenge, padding);

            //apply recovery function
            byte[] encryptedPin = PublicKeyCertificate.DecryptRSA(pinData, iccKey.Modulus, iccKey.Exponent);
            return(encryptedPin);
        }