CIS 3223. Data Structures and Algorithms

Algorithms with numbers

 

1. Basic arithmetic of binary numbers

Addition: suppose x and y are each n bits long (so x < 2n, or n > log x, and same for y), and addition is done bit-by-bit, then it takes O(n) time.

How about adding multiple bits at the same time? Addition cannot use less than linear time. Subtraction is similar to addition.

Simple operations of arithmetic logic unit: constant time

CPU: word size and clock rate

Multiplication: to multiply x and y by O(n) addition-shift takes O(n2) time. The textbook gives an alternative algorithm with the same complexity.

Division (and remainder): a recursive algorithm (Figure 1.2) takes O(n2) time, too. Try divide(5, 2)

 

2. Modular arithmetic

Integers x and y are congruent modulo N, if they differ by a multiple of N, that is, xy (mod N) ⇔ N divides (x - y).

Given x and y in [0, N-1], modular addition [(x + y) mod N] can be done using an addition followed by an optional subtraction, and modular multiplication [(x * y) mod N] using a multiplication followed by a division. Their complexity are still O(n) and O(n2), respectively.

Modular exponentiation: [xy mod N]. Directly calculate xy with y-1 multiplications would take too long. The algorithm in Figure 1.4 does O(n) recursive calls, and each of them takes O(n2) time, so the complexity is O(n3).

Euclid's algorithm for greatest common divisor (Figure 1.5) and its extension (Figure 1.6). Both take O(n3) time, since each recursion at least reduces the larger argument in half, as proved in the textbook.

Modular division: this operation is not defined as an integer division followed by a modulo, but as the reverse operation of modular multiplication. When gcd(x, N) = 1 (i.e., the two numbers are relatively prime), [(y / x) mod N] is carried out as [(y * a) mod N], where [ax ≡ 1 (mod N)], so a is the multiplicative inverse of x (mod N), written as x-1. To calculate x-1 from x and N, using the extended Euclid's algorithm to find integer b, so that bx + cN ≡ 1, then the positive integer a = (b mod N) is x-1. Overall, modular division takes O(n3) time.

 

3. Primality

Primality testing: check if a given integer is a prime number. To directly factor the number may take too long.

Fermat's little theorem: If p is prime, then for every 1 ≤ a < p, ap-1 ≡ 1 (mod p).

Therefore, random testing can be used to test the primality of a number, as given in Figure 1.7. The "Yes" answer of the algorithm should be taken as "Maybe". A more reliable algorithm can be obtained by repeating the test (Figure 1.8).

A random n-bit number has roughly 1/n chance of being prime, so in average it takes O(n) tests to generate a random prime number.

 

4. Cryptography

Using a key (string) to encrypt/decrypt. Basic assumption: it is unlikely for the key to be guessed.

Private key scheme: use the same key for encryption and decryption. Example: Exclusive-OR

Public key scheme: the key used to encrypt a message differs from the key used to decrypt it. Example: RSA (Figure 1.9). Program: PGP