Ejemplo n.º 1
0
Archivo: rsa.go Proyecto: 8l/go-learn
// randomNumber returns a uniform random value in [0, max).
func randomNumber(rand io.Reader, max *big.Int) (n *big.Int, err os.Error) {
	k := (max.Len() + 7) / 8

	// r is the number of bits in the used in the most significant byte of
	// max.
	r := uint(max.Len() % 8)
	if r == 0 {
		r = 8
	}

	bytes := make([]byte, k)
	n = new(big.Int)

	for {
		_, err = io.ReadFull(rand, bytes)
		if err != nil {
			return
		}

		// Clear bits in the first byte to increase the probability
		// that the candidate is < max.
		bytes[0] &= uint8(int(1<<r) - 1)

		n.SetBytes(bytes)
		if big.CmpInt(n, max) < 0 {
			return
		}
	}

	return
}
Ejemplo n.º 2
0
Archivo: rsa.go Proyecto: 8l/go-learn
// modInverse returns ia, the inverse of a in the multiplicative group of prime
// order n. It requires that a be a member of the group (i.e. less than n).
func modInverse(a, n *big.Int) (ia *big.Int) {
	g := new(big.Int)
	x := new(big.Int)
	y := new(big.Int)
	big.GcdInt(g, x, y, a, n)
	if big.CmpInt(x, bigOne) < 0 {
		// 0 is not the multiplicative inverse of any element so, if x
		// < 1, then x is negative.
		x.Add(x, n)
	}

	return x
}
Ejemplo n.º 3
0
Archivo: rsa.go Proyecto: 8l/go-learn
// decrypt performs an RSA decryption, resulting in a plaintext integer. If a
// random source is given, RSA blinding is used.
func decrypt(rand io.Reader, priv *PrivateKey, c *big.Int) (m *big.Int, err os.Error) {
	// TODO(agl): can we get away with reusing blinds?
	if big.CmpInt(c, priv.N) > 0 {
		err = DecryptionError{}
		return
	}

	var ir *big.Int
	if rand != nil {
		// Blinding enabled. Blinding involves multiplying c by r^e.
		// Then the decryption operation performs (m^e * r^e)^d mod n
		// which equals mr mod n. The factor of r can then be removed
		// by multipling by the multiplicative inverse of r.

		r, err1 := randomNumber(rand, priv.N)
		if err1 != nil {
			err = err1
			return
		}
		if big.CmpInt(r, bigZero) == 0 {
			r = bigOne
		}
		ir = modInverse(r, priv.N)
		bigE := big.NewInt(int64(priv.E))
		rpowe := new(big.Int).Exp(r, bigE, priv.N)
		c.Mul(c, rpowe)
		c.Mod(c, priv.N)
	}

	m = new(big.Int).Exp(c, priv.D, priv.N)

	if ir != nil {
		// Unblind.
		m.Mul(m, ir)
		m.Mod(m, priv.N)
	}

	return
}
Ejemplo n.º 4
0
Archivo: rsa.go Proyecto: 8l/go-learn
func (priv PrivateKey) Validate() os.Error {
	/*
		TODO(agl): Enable once big implements ProbablyPrime.

		// Check that p and q are prime.
		if !priv.P.ProbablyPrime(20) {
			return os.ErrorString("P is composite");
		}
		if !priv.Q.ProbablyPrime(20) {
			return os.ErrorString("Q is composite");
		}
	*/
	// Check that p*q == n.
	modulus := new(big.Int).Mul(priv.P, priv.Q)
	if big.CmpInt(modulus, priv.N) != 0 {
		return os.ErrorString("invalid modulus")
	}
	// Check that e and totient(p, q) are coprime.
	pminus1 := new(big.Int).Sub(priv.P, bigOne)
	qminus1 := new(big.Int).Sub(priv.Q, bigOne)
	totient := new(big.Int).Mul(pminus1, qminus1)
	e := big.NewInt(int64(priv.E))
	gcd := new(big.Int)
	x := new(big.Int)
	y := new(big.Int)
	big.GcdInt(gcd, x, y, totient, e)
	if big.CmpInt(gcd, bigOne) != 0 {
		return os.ErrorString("invalid public exponent E")
	}
	// Check that de ≡ 1 (mod totient(p, q))
	de := new(big.Int).Mul(priv.D, e)
	de.Mod(de, totient)
	if big.CmpInt(de, bigOne) != 0 {
		return os.ErrorString("invalid private exponent D")
	}
	return nil
}