Schoolbook multiplication computes the exact product in m + n limbs full
This proof shows: correctness, termination.
Let β=2w, let a=[a0,…,am−1] and b=[b0,…,bn−1] be arrays of limbs (0≤ai,bj≤β−1), and let A=∑iaiβi and B=∑jbjβj. For an array c of m+n entries write V(c)=∑k=0m+n−1ckβk, and Ai=∑i′<iai′βi′, so A0=0 and Am=A.
Theorem. SCHOOLBOOK-MUL(a,b) terminates and returns an array c of m+n limbs, each in [0,β−1], with V(c)=AB.
Proof. Both loops have fixed bounds, so the procedure terminates after mn runs of the inner body. We prove an invariant of the outer loop.
(O) Before row i (that is, before line L3 with this i), each ck is a limb, ck=0 for each k≥i+n, and V(c)=Ai⋅B.
Initialization. Line L1 sets all ck=0, so V(c)=0=A0B, and every ck is 0.
Maintenance. Fix i with 0≤i<m and assume (O). Let c(0) be the array before row i. For the inner loop we prove:
(I) Before step j of the inner loop (0≤j≤n), 0≤carry≤β−1, the entries ci,…,ci+j−1 are limbs, the other entries are those of c(0), and
k=i∑i+j−1ckβk+carry⋅βi+j=k=i∑i+j−1ck(0)βk+ai(j′<j∑bj′βj′)βi.
For j=0, line L3 sets carry to 0 and both sides are 0. In step j, line L5 forms t=ci+j(0)+aibj+carry; the entry ci+j is still the old one by (I). All three terms are nonnegative, and t≤(β−1)+(β−1)2+(β−1)=β2−1. Lines L6 and L7 write t=ci+j+carry′β with ci+j=tmodβ∈[0,β−1] and carry′=⌊t/β⌋≤⌊(β2−1)/β⌋=β−1. So
ci+jβi+j+carry′βi+j+1=tβi+j=ci+j(0)βi+j+carry⋅βi+j+aibjβi+j. Adding this to (I) for j gives (I) for j+1.
After the inner loop, (I) with j=n holds. Line L8 stores carry in ci+n. By (O), ci+n(0)=0, so this store adds carry⋅βi+n to V(c) and replaces nothing. Hence, with (I) for j=n, the new array satisfies
V(c)=V(c(0))+aiBβi=AiB+aiβiB=Ai+1B. Each entry is a limb: the entries ci,…,ci+n−1 by (I), ci+n=carry≤β−1, and the others are unchanged. The entries with index k≥i+1+n were not written in row i, so they are still 0. Thus (O) holds for i+1.
Termination. For i=m, (O) gives V(c)=AmB=AB, with every entry a limb. Line L9 returns this array, of m+n limbs. ■
Remark (no row writes a fresh position twice). The maintenance step uses ci+n(0)=0. This is the second part of (O): row i′<i writes only positions i′,…,i′+n, all below i+n.
Remark (signs). For signed inputs, AB=sign(A)sign(B)∣A∣∣B∣, so multiplying the magnitudes with this procedure and setting the sign by the product of the signs is correct; a zero product is given the sign +.