diff -r 2d3f731e2eb1 src/pkg/crypto/rsa/rsa.go
--- a/src/pkg/crypto/rsa/rsa.go	Fri Mar 11 18:18:59 2011 -0800
+++ b/src/pkg/crypto/rsa/rsa.go	Sun Mar 13 20:11:52 2011 +0100
@@ -359,7 +359,38 @@
 		c.Mod(c, priv.N)
 	}
 
-	m = new(big.Int).Exp(c, priv.D, priv.N)
+	if priv.P == nil || priv.Q == nil {
+		m = new(big.Int).Exp(c, priv.D, priv.N)
+	} else {
+		/*
+		m = c^d mod n
+
+		same using chinese remainder theorem:
+
+		m1 = c ^ (d mod (p-1)) mod p
+		m2 = c ^ (d mod (q-1)) mod q
+		h = (p^-1 mod q) * (m2 - m1) mod q
+		m = m1 + h * p
+		*/
+
+		h := new(big.Int)
+		h.Sub(priv.P, bigOne)
+		h.Mod(priv.D, h)
+		m = new(big.Int).Exp(c, h, priv.P)
+		h.Sub(priv.Q, bigOne)
+		h.Mod(priv.D, h)
+		m2 := new(big.Int).Exp(c, h, priv.Q)
+
+		h.ModInverse(priv.P, priv.Q)
+		m2.Sub(m2, m)
+		if m2.Sign() < 0 {
+			m2.Add(m2, priv.Q)
+		}
+		h.Mul(h, m2)
+		h.Mod(h, priv.Q)
+		h.Mul(h, priv.P)
+		m.Add(m, h)
+	}
 
 	if ir != nil {
 		// Unblind.
