Beispiel #1
0
    /// <summary>
    /// Test the crypto
    /// </summary>
    static void Main(string[] args)
    {
        Console.WriteLine("Testing RSA");

        //SimpleBignum p = new SimpleBignum("dd755ca44f2f399a845690ef8507365befef9505fbf416cb0b306bd13221a00368e8bd45f7357d2686b8437816da326dc40b7c756d2407bb9a8c8a3fb2b8e79d");
        //SimpleBignum q = new SimpleBignum("e083f0abbd0bee477bc86aa12077b82b5f7a035ac614dd494fa55a57e03deea0527f54e31e715374b3dd992ea9f80bb94b7e3b2b4e02e8901af79e688c1c7483");
        //SimpleBignum m = new SimpleBignum("5468697320697320676f696e6720746f20626520656d626172726173696e6720696620697420646f65736e277420776f726b21");
        //SimpleBignum c = new SimpleBignum("68c1a28435c90c20e3e0111302f97222c875215ce37178cdca30fbd90fceafaa7aa90c5d0dee2290a3b4cf944a177175acd5cb29cb03869bce2b4f93357cb94b08f8f1f08f793f9a7015338be19ff6b9301aa144665ffe0f7749885d3c3a51f8627d1e26ad629525eee59da7d5c69fe2926b6fb51ded336b6033a203d1ef5bc3");
        SimpleBignum e = new SimpleBignum("010001");
        SimpleBignum n = new SimpleBignum("c238d450c526bb2014b1489505540eb8330c7e01ed7ac4a7d9a52423025f9bdd5eb42b2103b6a069e43678bef68fa67703c304c590c6629bd455f4d8c0a145599df37bdefa19b52532937a2ccc22fb36f73c6dad819bc01e1326028fab37a052e0efae05e437573f2254a5ea4a43d1f3dbec2b22bf24fc6dddd0443f6ebda957");
        SimpleBignum d = new SimpleBignum("305bf211826558666e808deffcf9a7089a3d5c0aa2d4d4ae6e74be00b19098c08fda107b11efa1157cab4b7950ef07a5ce9bfa4e2ef4168d725b4cb1c394e42d332999fa20a42f4c31fdeba079c6931a11915f66d2b47c75571d334ce075bc417df8bc0848ae97b7abf6472ab7c83de2da691115a864d32496200d26a1d91791");

        string       msg = "This is going to be embarrasing if it doesn't work!";
        SimpleBignum m   = SimpleBignum.FromText(msg);

        Console.WriteLine("Message (text): {0}", msg);
        Console.WriteLine("Message (num):  {0}", m);

        Console.WriteLine("Encrypting (should be 68c1...5bc3):");
        SimpleBignum c = m.PowMod(e, n);

        Console.WriteLine("Encrypted: {0}", c);

        Console.WriteLine("Decrypting (please wait, this algorithm isn't optimised):");
        SimpleBignum a     = c.PowMod(d, n);
        string       aText = a.ToText();

        Console.WriteLine("Decrypted (num):  {0}", a);
        Console.WriteLine("Decrypted (text): {0}", aText);
    }
Beispiel #2
0
    /// <summary>
    /// Finds the remainder of a/b, using the shift and subtract method
    /// </summary>
    public static SimpleBignum operator %(SimpleBignum a, SimpleBignum b)
    {
        SimpleBignum result = new SimpleBignum(a); // Start off with out=a, and whittle it down
        int          len_a  = a.SignificantBytes;  // Get the lengths
        int          len_b  = b.SignificantBytes;

        if (len_b > len_a)
        {
            return(result);                             // Simple case: since b is bigger, a is already the modulus
        }
        int          byte_shifts = len_a - len_b + 1;   // Figure out how many shifts needed to make b bigger than a
        SimpleBignum shifted     = new SimpleBignum(b); // shifted = b

        shifted.ShiftLeftDigits(byte_shifts);           // Now b is shifted bigger than a
        // Now do a series of bit shifts on B, subtracting it from A each time
        for (int i = 0; i < byte_shifts * 8; i++)
        {
            shifted.ShiftRight1Bit();

            if (result >= shifted)
            {
                result -= shifted;
            }
        }
        return(result);
    }
Beispiel #3
0
 /// <summary>
 /// Adds two big nums, using the school method
 /// </summary>
 public static SimpleBignum operator +(SimpleBignum a, SimpleBignum b)
 {
   SimpleBignum result = new SimpleBignum();
   int carry = 0;
   for (int i = 0; i < MaxDigits; i++)
   {
     int newval = a.digits[i] + b.digits[i] + carry;
     result.digits[i] = (byte)(newval % 256);
     carry = (byte)(newval / 256);
   }
   return result;
 }
Beispiel #4
0
    /// <summary>
    /// Multiply a bignum by 1 digit
    /// </summary>
    SimpleBignum Mult1(int mult)
    {
        SimpleBignum result = new SimpleBignum();
        int          carry  = 0;

        for (int i = 0; i < MaxDigits; i++)
        {
            int newval = digits[i] * mult + carry;
            result.digits[i] = (byte)(newval % 256);
            carry            = (byte)(newval / 256);
        }
        return(result);
    }
Beispiel #5
0
    /// <summary>
    /// Adds two big nums, using the school method
    /// </summary>
    public static SimpleBignum operator +(SimpleBignum a, SimpleBignum b)
    {
        SimpleBignum result = new SimpleBignum();
        int          carry  = 0;

        for (int i = 0; i < MaxDigits; i++)
        {
            int newval = a.digits[i] + b.digits[i] + carry;
            result.digits[i] = (byte)(newval % 256);
            carry            = (byte)(newval / 256);
        }
        return(result);
    }
Beispiel #6
0
    /// <summary>
    /// Multiplies using the method you were taught at school. Not the fastest but it'll do.
    /// Eg multiply by each shifted digit individually, totalling as it goes
    /// </summary>
    public static SimpleBignum operator *(SimpleBignum a, SimpleBignum b)
    {
        SimpleBignum result = new SimpleBignum();
        SimpleBignum temp; // This is used to store the multiplication by each digit

        for (int i = 0; i < MaxDigits; i++)
        {
            if (b.digits[i] > 0)
            {                                // Save time by skipping multiplying by zero columns
                temp = a.Mult1(b.digits[i]); // temp = a * single-digit-from-b
                temp.ShiftLeftDigits(i);     // temp is shifted to line up with the column we're using from b
                result += temp;              // Add temp to the running total
            }
        }
        return(result);
    }
Beispiel #7
0
    /// <summary>
    /// Power Modulus: this ^ power % mod
    /// This does modular exponentiation using the right-to-left binary method
    /// This is actually quite slow, mainly due to the mod function, but also the mult is slow too
    /// Clobbers power
    /// </summary>
    public SimpleBignum PowMod(SimpleBignum power, SimpleBignum mod)
    {
        SimpleBignum result  = new SimpleBignum("01"); // result = 1
        SimpleBignum baseNum = new SimpleBignum(this); // Make a copy of this

        while (power.GreaterThanZero)                  // while power > 0
        {
            if ((power.digits[0] & 1) == 1)            // If lowest bit is set
            {
                result = (result * baseNum) % mod;     // result = result*base % mod
            }
            baseNum = (baseNum * baseNum) % mod;       // base = base^2 % mod

            power.ShiftRight1Bit();                    // power>>=1
        }

        return(result);
    }
Beispiel #8
0
 /// <summary>
 /// Do a - b, undefined if b is bigger
 /// </summary>
 public static SimpleBignum operator -(SimpleBignum a, SimpleBignum b)
 {
   SimpleBignum result = new SimpleBignum();
   // Basically go from least significant to most significant, subtracting a digit at a time, and
   // borrowing 1 from the next digit if the result is negative. Just like the pen + paper method.
   int borrow = 0;
   for (int i = 0; i < MaxDigits; i++)
   {
     int newval = a.digits[i] - b.digits[i] - borrow;
     if (newval < 0)
     {
       newval += 256;
       borrow = 1;
     }
     else
     {
       borrow = 0;
     }
     result.digits[i] = (byte)newval;
   }
   return result;
 }
Beispiel #9
0
    /// <summary>
    /// Do a - b, undefined if b is bigger
    /// </summary>
    public static SimpleBignum operator -(SimpleBignum a, SimpleBignum b)
    {
        SimpleBignum result = new SimpleBignum();
        // Basically go from least significant to most significant, subtracting a digit at a time, and
        // borrowing 1 from the next digit if the result is negative. Just like the pen + paper method.
        int borrow = 0;

        for (int i = 0; i < MaxDigits; i++)
        {
            int newval = a.digits[i] - b.digits[i] - borrow;
            if (newval < 0)
            {
                newval += 256;
                borrow  = 1;
            }
            else
            {
                borrow = 0;
            }
            result.digits[i] = (byte)newval;
        }
        return(result);
    }
Beispiel #10
0
 /// <summary>
 /// Multiply a bignum by 1 digit
 /// </summary>
 SimpleBignum Mult1(int mult)
 {
   SimpleBignum result = new SimpleBignum();
   int carry = 0;
   for (int i = 0; i < MaxDigits; i++)
   {
     int newval = digits[i] * mult + carry;
     result.digits[i] = (byte)(newval % 256);
     carry = (byte)(newval / 256);
   }
   return result;
 }
Beispiel #11
0
 /// <summary>
 /// Creates a new bignum by copying the value of an existing one
 /// </summary>
 public SimpleBignum(SimpleBignum source)
 {
   Array.Copy(source.digits, digits, MaxDigits);
 }
Beispiel #12
0
  /// <summary>
  /// Test the crypto
  /// </summary>
  static void Main(string[] args)
  {
    Console.WriteLine("Testing RSA");

    //SimpleBignum p = new SimpleBignum("dd755ca44f2f399a845690ef8507365befef9505fbf416cb0b306bd13221a00368e8bd45f7357d2686b8437816da326dc40b7c756d2407bb9a8c8a3fb2b8e79d");
    //SimpleBignum q = new SimpleBignum("e083f0abbd0bee477bc86aa12077b82b5f7a035ac614dd494fa55a57e03deea0527f54e31e715374b3dd992ea9f80bb94b7e3b2b4e02e8901af79e688c1c7483");
    //SimpleBignum m = new SimpleBignum("5468697320697320676f696e6720746f20626520656d626172726173696e6720696620697420646f65736e277420776f726b21");
    //SimpleBignum c = new SimpleBignum("68c1a28435c90c20e3e0111302f97222c875215ce37178cdca30fbd90fceafaa7aa90c5d0dee2290a3b4cf944a177175acd5cb29cb03869bce2b4f93357cb94b08f8f1f08f793f9a7015338be19ff6b9301aa144665ffe0f7749885d3c3a51f8627d1e26ad629525eee59da7d5c69fe2926b6fb51ded336b6033a203d1ef5bc3");
    SimpleBignum e = new SimpleBignum("010001");
    SimpleBignum n = new SimpleBignum("c238d450c526bb2014b1489505540eb8330c7e01ed7ac4a7d9a52423025f9bdd5eb42b2103b6a069e43678bef68fa67703c304c590c6629bd455f4d8c0a145599df37bdefa19b52532937a2ccc22fb36f73c6dad819bc01e1326028fab37a052e0efae05e437573f2254a5ea4a43d1f3dbec2b22bf24fc6dddd0443f6ebda957");
    SimpleBignum d = new SimpleBignum("305bf211826558666e808deffcf9a7089a3d5c0aa2d4d4ae6e74be00b19098c08fda107b11efa1157cab4b7950ef07a5ce9bfa4e2ef4168d725b4cb1c394e42d332999fa20a42f4c31fdeba079c6931a11915f66d2b47c75571d334ce075bc417df8bc0848ae97b7abf6472ab7c83de2da691115a864d32496200d26a1d91791");

    string msg = "This is going to be embarrasing if it doesn't work!";
    SimpleBignum m = SimpleBignum.FromText(msg);
    Console.WriteLine("Message (text): {0}", msg);
    Console.WriteLine("Message (num):  {0}", m);

    Console.WriteLine("Encrypting (should be 68c1...5bc3):");
    SimpleBignum c = m.PowMod(e, n);
    Console.WriteLine("Encrypted: {0}", c);

    Console.WriteLine("Decrypting (please wait, this algorithm isn't optimised):");
    SimpleBignum a = c.PowMod(d, n);
    string aText = a.ToText();
    Console.WriteLine("Decrypted (num):  {0}", a);
    Console.WriteLine("Decrypted (text): {0}", aText);
  }
Beispiel #13
0
  /// <summary>
  /// Power Modulus: this ^ power % mod
  /// This does modular exponentiation using the right-to-left binary method
  /// This is actually quite slow, mainly due to the mod function, but also the mult is slow too
  /// Clobbers power
  /// </summary>
  public SimpleBignum PowMod(SimpleBignum power, SimpleBignum mod)
  {
    SimpleBignum result = new SimpleBignum("01"); // result = 1
    SimpleBignum baseNum = new SimpleBignum(this); // Make a copy of this

    while (power.GreaterThanZero) // while power > 0
    {
      if ((power.digits[0] & 1) == 1) // If lowest bit is set
        result = (result * baseNum) % mod; // result = result*base % mod

      baseNum = (baseNum * baseNum) % mod; // base = base^2 % mod

      power.ShiftRight1Bit(); // power>>=1
    }

    return result;
  }
Beispiel #14
0
  /// <summary>
  /// Finds the remainder of a/b, using the shift and subtract method
  /// </summary>
  public static SimpleBignum operator %(SimpleBignum a, SimpleBignum b)
  {
    SimpleBignum result = new SimpleBignum(a); // Start off with out=a, and whittle it down 
    int len_a = a.SignificantBytes; // Get the lengths
    int len_b = b.SignificantBytes;
    if (len_b > len_a) return result; // Simple case: since b is bigger, a is already the modulus
    int byte_shifts = len_a - len_b + 1; // Figure out how many shifts needed to make b bigger than a
    SimpleBignum shifted = new SimpleBignum(b); // shifted = b
    shifted.ShiftLeftDigits(byte_shifts); // Now b is shifted bigger than a
    // Now do a series of bit shifts on B, subtracting it from A each time
    for (int i = 0; i < byte_shifts * 8; i++)
    {
      shifted.ShiftRight1Bit();

      if (result >= shifted)
        result -= shifted;
    }
    return result;
  }
Beispiel #15
0
 /// <summary>
 /// Multiplies using the method you were taught at school. Not the fastest but it'll do.
 /// Eg multiply by each shifted digit individually, totalling as it goes
 /// </summary>
 public static SimpleBignum operator *(SimpleBignum a, SimpleBignum b)
 {
   SimpleBignum result = new SimpleBignum();
   SimpleBignum temp; // This is used to store the multiplication by each digit
   for (int i = 0; i < MaxDigits; i++)
   {
     if (b.digits[i] > 0)
     { // Save time by skipping multiplying by zero columns
       temp = a.Mult1(b.digits[i]); // temp = a * single-digit-from-b
       temp.ShiftLeftDigits(i); // temp is shifted to line up with the column we're using from b
       result += temp; // Add temp to the running total
     }
   }
   return result;
 }
Beispiel #16
0
 /// <summary>
 /// Creates a new bignum by copying the value of an existing one
 /// </summary>
 public SimpleBignum(SimpleBignum source)
 {
     Array.Copy(source.digits, digits, MaxDigits);
 }