1

I have the following code:

BigInteger b = new BigInteger(12345678912345678912);
var modedInteger = b * 3712931 % (2 ^ 64);

Given this, how would I get the value of b from modedInteger? I saw that we can use BigInteger.ModPow() but I am not sure...

Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
DinoMan
  • 35
  • 5

1 Answers1

2

Well, you can try starting from Extended Euclid Algorithm, e.g. (let it be implemented as extension methods)

    public static (BigInteger LeftFactor,
               BigInteger RightFactor,
               BigInteger Gcd) Egcd(this BigInteger left, BigInteger right) {
      BigInteger leftFactor = 0;
      BigInteger rightFactor = 1;

      BigInteger u = 1;
      BigInteger v = 0;
      BigInteger gcd = 0;

      while (left != 0) {
        BigInteger q = right / left;
        BigInteger r = right % left;

        BigInteger m = leftFactor - u * q;
        BigInteger n = rightFactor - v * q;

        right = left;
        left = r;
        leftFactor = u;
        rightFactor = v;
        u = m;
        v = n;

        gcd = right;
      }

      return (LeftFactor: leftFactor,
              RightFactor: rightFactor,
              Gcd: gcd);
    }

Then you can continue with mod inversion and mod division:

    public static BigInteger ModInversion(this BigInteger value, BigInteger modulo) {
      var egcd = Egcd(value, modulo);

      if (egcd.Gcd != 1)
        throw new ArgumentException("Invalid modulo", nameof(modulo));

      BigInteger result = egcd.LeftFactor;

      if (result < 0)
        result += modulo;

      return result % modulo;
    }

    public static BigInteger ModDivision(
      this BigInteger left, BigInteger right, BigInteger modulo) =>
           (left * ModInversion(right, modulo)) % modulo;

Finally, your test:

  BigInteger b = new BigInteger(12345678912345678912);

  //DONE: Please, note that ^ stands for XOR, so 2 ^ 64 == 66
  BigInteger mod = BigInteger.Pow(2, 64);

  var modedInteger = b * 3712931 % mod;

  BigInteger result = modedInteger.ModDivision(3712931, mod);

  Console.Write(result);

Outcome:

 12345678912345678912
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215