/* * Decryption using chinese remainder theorem */ //public BigInteger decrypt(BigInteger c) //{ // // L_p(c^p-1) // mp = (((BigInteger.ModPow(c, p_minus1, p_square) - 1) / p) * hp) % p; // // L_q(c^q-1) // mq = (((BigInteger.ModPow(c, q_minus1, q_square) - 1) / q) * hq) % q; // // ( mp*eq + mq*ep ) % n // return (mp * eq + mq * ep) % n; //} /* * Encryption ( (1 + m*n) * r^n mod n^2 ) * Computing r^n using CRT. */ //public BigInteger encrypt(BigInteger m) //{ // BigInteger r = RandomInt(keyBitLength) % n; // mp = BigInteger.ModPow(r, n, p_square); // mq = BigInteger.ModPow(r, n, q_square); // r = (mp * eq2 + mq * ep2) % n_square; // return (((n * m + 1) % n_square) * r) % n_square; //} /* * Decryption ( ((c^lambda) % n^2 - 1) div n ) * lambda^(-1) ) % n */ private BigInteger decrypt(BigInteger c) { if (c >= n_square) { GuiLogMessage("Cipher is bigger than N^2 - this will produce a wrong result!", NotificationLevel.Warning); } BigInteger lambdainv = BigIntegerHelper.ModInverse(InputLambda, n); return((((BigInteger.ModPow(c, InputLambda, n_square) - 1) / n) * lambdainv) % n); }
// not used, public/private keys are input variables for this plugin private void generateKeys() { BigInteger twoPowModulusBits, n_plus1; p = BigIntegerHelper.RandomPrimeBits(keyBitLength - (keyBitLength / 2)); q = BigIntegerHelper.RandomPrimeBits(keyBitLength / 2); n = p * q; // Just complete PK: n^2 n_plus1 = n + 1; n_square = n * n; // compute lambda p_minus1 = p - 1; q_minus1 = q - 1; lambda = BigIntegerHelper.LCM(p_minus1, q_minus1); // Compute n^(-1) twoPowModulusBits = 1 << keyBitLength; n_inv = BigIntegerHelper.ModInverse(n, twoPowModulusBits); // Store the L(lambda)-part for decryption decDiv = BigInteger.ModPow(n + 1, lambda, n_square); decDiv = BigIntegerHelper.ModInverse(L(decDiv), n); p_square = p * p; q_square = q * q; hp = BigIntegerHelper.ModInverse((BigInteger.ModPow(n + 1, p_minus1, p_square) - 1) / p, p); hq = BigIntegerHelper.ModInverse((BigInteger.ModPow(n + 1, q_minus1, q_square) - 1) / q, q); // for CRT BigInteger s, t; BigIntegerHelper.ExtEuclid(p, q, out s, out t); ep = s * p; eq = t * q; // CRT Encryption: BigIntegerHelper.ExtEuclid(p_square, q_square, out s, out t); ep2 = s * p_square; eq2 = t * q_square; }
/// <summary> /// Implementation of solutionfinding for chinese remainder theorem. /// i.e. finding an x that fullfills /// x = a1 (mod m1) /// x = a2 (mod m2) /// ... /// </summary> /// <param name="congruences">The congruences (a_i, m_i)</param> /// <returns>the value that fits into all congruences</returns> private BigInteger CRT(List <KeyValuePair <BigInteger, BigInteger> > congruences) { BigInteger x = 0; for (int i = 0; i < congruences.Count; i++) { BigInteger k = 1; for (int c = 0; c < congruences.Count; c++) { if (c != i) { k *= congruences[c].Value; } } BigInteger r = BigIntegerHelper.ModInverse(k, congruences[i].Value); x += congruences[i].Key * r * k; } return(x); }
/* * Compute: res = E(-m) * Computes the multiplicative inverse of some ciphertext c = E(m). */ private BigInteger cipherNeg(BigInteger c) { return(BigIntegerHelper.ModInverse(c, n_square)); }
/// <summary> /// Main method /// </summary> public void Execute() { BigInteger result = 0; //First checks if both inputs are set if (input1 != null && input2 != null) { ProgressChanged(0.5, 1.0); try { //As the user changes the operation different outputs are calculated. switch (settings.Operat) { // x + y case 0: result = Input1 + Input2; break; // x - y case 1: result = Input1 - Input2; break; //x * y case 2: result = Input1 * Input2; break; // x / y case 3: result = Input1 / Input2; break; // x ^ y case 4: if (Mod != 0) { if (Input2 >= 0) { result = BigInteger.ModPow(Input1, Input2, Mod); } else { result = BigInteger.ModPow(BigIntegerHelper.ModInverse(Input1, Mod), -Input2, Mod); } } else { result = BigIntegerHelper.Pow(Input1, Input2); } break; // gcd(x,y) case 5: result = Input1.GCD(Input2); break; // lcm(x,y) case 6: result = Input1.LCM(Input2); break; // sqrt(x,y) case 7: result = Input1.Sqrt(); break; // modinv(x,y) case 8: if (Input2 != 0) { result = BigIntegerHelper.ModInverse(Input1, Input2); } else { result = 1 / Input1; } break; // phi(x) case 9: result = Input1.Phi(); break; } Output = (Mod == 0) ? result : (((result % Mod) + Mod) % Mod); } catch (Exception e) { GuiLogMessage("Big Number fail: " + e.Message, NotificationLevel.Error); return; } ProgressChanged(1.0, 1.0); } }
/// <summary> /// Called by the environment to start generating of public/private keys /// </summary> public void Execute() { BigInteger p; BigInteger q; BigInteger n; BigInteger e; BigInteger d; ProgressChanged(0.0, 1.0); switch (settings.Source) { // manual case 0: try { p = BigIntegerHelper.ParseExpression(settings.P); q = BigIntegerHelper.ParseExpression(settings.Q); e = BigIntegerHelper.ParseExpression(settings.E); if (!BigIntegerHelper.IsProbablePrime(p)) { GuiLogMessage(p.ToString() + " is not prime!", NotificationLevel.Error); return; } if (!BigIntegerHelper.IsProbablePrime(q)) { GuiLogMessage(q.ToString() + " is not prime!", NotificationLevel.Error); return; } if (p == q) { GuiLogMessage("The primes P and Q can not be equal!", NotificationLevel.Error); return; } } catch (Exception ex) { GuiLogMessage("Invalid Big Number input: " + ex.Message, NotificationLevel.Error); return; } try { D = BigIntegerHelper.ModInverse(e, (p - 1) * (q - 1)); } catch (Exception) { GuiLogMessage("RSAKeyGenerator Error: E (" + e + ") can not be inverted.", NotificationLevel.Error); return; } try { N = p * q; E = e; } catch (Exception ex) { GuiLogMessage("Big Number fail: " + ex.Message, NotificationLevel.Error); return; } break; case 1: try { n = BigIntegerHelper.ParseExpression(settings.N); d = BigIntegerHelper.ParseExpression(settings.D); e = BigIntegerHelper.ParseExpression(settings.E); } catch (Exception ex) { GuiLogMessage("Invalid Big Number input: " + ex.Message, NotificationLevel.Error); return; } try { N = n; E = e; D = d; } catch (Exception ex) { GuiLogMessage("Big Number fail: " + ex.Message, NotificationLevel.Error); return; } break; //randomly generated case 2: try { n = BigInteger.Parse(this.settings.Range); switch (this.settings.RangeType) { case 0: // n = number of bits for primes if ((int)n <= 2) { GuiLogMessage("Value for n has to be greater than 2.", NotificationLevel.Error); return; } if (n >= 1024) { GuiLogMessage("Please note that the generation of prime numbers with " + n + " bits may take some time...", NotificationLevel.Warning); } // calculate the number of expected tries for the indeterministic prime number generation using the density of primes in the given region BigInteger limit = ((BigInteger)1) << (int)n; limittries = (int)(BigInteger.Log(limit) / 6); expectedtries = 2 * limittries; tries = 0; p = this.RandomPrimeBits((int)n); tries = limittries; limittries = expectedtries; do { q = this.RandomPrimeBits((int)n); } while (p == q); break; case 1: // n = upper limit for primes default: if (n <= 4) { GuiLogMessage("Value for n has to be greater than 4", NotificationLevel.Error); return; } p = BigIntegerHelper.RandomPrimeLimit(n + 1); ProgressChanged(0.5, 1.0); do { q = BigIntegerHelper.RandomPrimeLimit(n + 1); } while (p == q); break; } } catch { GuiLogMessage("Please enter an integer value for n.", NotificationLevel.Error); return; } BigInteger phi = (p - 1) * (q - 1); // generate E for the given values of p and q bool found = false; foreach (var ee in new BigInteger[] { 3, 5, 7, 11, 17, 65537 }) { if (ee < phi && ee.GCD(phi) == 1) { E = ee; found = true; break; } } if (!found) { for (int i = 0; i < 1000; i++) { e = BigIntegerHelper.RandomIntLimit(phi); if (e >= 2 && e.GCD(phi) == 1) { E = e; found = true; break; } } } if (!found) { GuiLogMessage("Could not generate a valid E for p=" + p + " and q=" + q + ".", NotificationLevel.Error); return; } N = p * q; D = BigIntegerHelper.ModInverse(E, phi); break; //using x509 certificate case 3: try { X509Certificate2 cert; RSAParameters par; if (this.settings.Password != "") { GuiLogMessage("Password entered. Try getting public and private key", NotificationLevel.Info); cert = new X509Certificate2(settings.CertificateFile, settings.Password, X509KeyStorageFlags.Exportable); if (cert == null || cert.PrivateKey == null) { throw new Exception("Private Key of X509Certificate could not be fetched"); } RSACryptoServiceProvider provider = (RSACryptoServiceProvider)cert.PrivateKey; par = provider.ExportParameters(true); } else { GuiLogMessage("No Password entered. Try loading public key only", NotificationLevel.Info); cert = new X509Certificate2(settings.CertificateFile); if (cert == null || cert.PublicKey == null || cert.PublicKey.Key == null) { throw new Exception("Private Key of X509Certificate could not be fetched"); } RSACryptoServiceProvider provider = (RSACryptoServiceProvider)cert.PublicKey.Key; par = provider.ExportParameters(false); } try { N = new BigInteger(par.Modulus); } catch (Exception ex) { GuiLogMessage("Could not get N from certificate: " + ex.Message, NotificationLevel.Warning); } try { E = new BigInteger(par.Exponent); } catch (Exception ex) { GuiLogMessage("Could not get E from certificate: " + ex.Message, NotificationLevel.Warning); } try { if (this.settings.Password != "") { D = new BigInteger(par.D); } else { D = 0; } } catch (Exception ex) { GuiLogMessage("Could not get D from certificate: " + ex.Message, NotificationLevel.Warning); } } catch (Exception ex) { GuiLogMessage("Could not load the selected certificate: " + ex.Message, NotificationLevel.Error); } break; } ProgressChanged(1.0, 1.0); }
public BigInteger[] Solve(List <BigInteger[]> matrix, BigInteger mod) { this.matrix = matrix; this.mod = mod; size = matrix.Count; this.rowSwaps = new int[matrix.Count]; for (int i = 0; i < matrix.Count; i++) { rowSwaps[i] = i; } //make lower triangular matrix: for (int x = 0; x < size; x++) { if ((matrix[x][x] % mod) == 0) { int y = x + 1; while (y < size && (matrix[y][x] % mod) == 0) { y++; } if (y == size) { int[] rowsToDelete = new int[size - (x + 1)]; for (int i = x + 1; i < size; i++) { rowsToDelete[i - (x + 1)] = rowSwaps[i]; } throw new LinearDependentException(rowsToDelete); } SwapRows(x, y); } BigInteger matrixXXinverse; try { matrixXXinverse = BigIntegerHelper.ModInverse(matrix[x][x], mod); } catch (ArithmeticException) { throw new NotInvertibleException(matrix[x][x] % mod); } for (int y = x + 1; y < size; y++) { if ((matrix[y][x] % mod) != 0) { SubAndMultiplyWithConstantRows(x, y, (matrixXXinverse * matrix[y][x]) % mod); } Debug.Assert((matrix[y][x] % mod) == 0); } } //make upper triangular matrix: for (int x = (size - 1); x >= 0; x--) { BigInteger matrixXXinverse; try { matrixXXinverse = BigIntegerHelper.ModInverse(matrix[x][x], mod); } catch (ArithmeticException) { throw new NotInvertibleException(matrix[x][x] % mod); } for (int y = x - 1; y >= 0; y--) { if ((matrix[y][x] % mod) != 0) { SubAndMultiplyWithConstantRows(x, y, (matrixXXinverse * matrix[y][x]) % mod); } Debug.Assert((matrix[y][x] % mod) == 0); } } //get solution: BigInteger[] sol = new BigInteger[size]; for (int x = 0; x < size; x++) { BigInteger matrixXXinverse = BigIntegerHelper.ModInverse(matrix[x][x], mod); sol[x] = (matrixXXinverse * matrix[x][size]) % mod; while (sol[x] < 0) { sol[x] += mod; } } return(sol); }
public void Execute() { ProgressChanged(0, 1); if (n < 2 * 3) { GuiLogMessage("Illegal Input N - DGK can not work", NotificationLevel.Error); return; } n_square = n * n; // check whether the sectret key is provided secretKeyValid = false; if (p != null && p != 0) { q = n / p; if (vp != null && vp > 0 && vq != null && vq > 0) { vpvq = vp * vq; secretKeyValid = true; } // for faster de-/encryption: pp_inv = BigIntegerHelper.ModInverse(p, q) * p; qq_inv = BigIntegerHelper.ModInverse(q, p) * q; } if (settings.Action == 0) // Encryption { if (InputM is BigInteger) { OutputC1 = encrypt((BigInteger)InputM); } else if (InputM is byte[]) { OutputC2 = BlockConvert((byte[])InputM, (u < 256)?256:u, n, encrypt, true); } } else if (settings.Action == 1) // Decryption { if (!secretKeyValid) { GuiLogMessage("Can't decrypt because secret key is not available", NotificationLevel.Error); return; } if (!decrypttableIsValid) { decrypttable = new BigInteger[(int)u]; BigInteger gv = BigInteger.ModPow(g, vp, p); //for (int i = 0; i < (int)u; i++) decrypttable[i] = BigInteger.ModPow(gv,i,p); decrypttableIsValid = true; dechash = new Hashtable(); for (int i = 0; i < (int)u; i++) { dechash[BigInteger.ModPow(gv, i, p) % (((BigInteger)1) << 48)] = i; } } if (InputM is BigInteger) { OutputC1 = decrypt((BigInteger)InputM); } else if (InputM is byte[]) { OutputC2 = removeZeros(BlockConvert((byte[])InputM, n, (u < 256)?256:u, decrypt, false)); } } // Make sure the progress bar is at maximum when your Execute() finished successfully. ProgressChanged(1, 1); }