Beispiel #1
0
// EncryptOAEP encrypts the given message with RSA-OAEP.
// The message must be no longer than the length of the public modulus less
// twice the hash length plus 2.
func EncryptOAEP(hash hash.Hash, rand io.Reader, pub *PublicKey, msg []byte, label []byte) (out []byte, err os.Error) {
	hash.Reset()
	k := (pub.N.Len() + 7) / 8
	if len(msg) > k-2*hash.Size()-2 {
		err = MessageTooLongError{}
		return
	}

	hash.Write(label)
	lHash := hash.Sum()
	hash.Reset()

	em := make([]byte, k)
	seed := em[1 : 1+hash.Size()]
	db := em[1+hash.Size():]

	copy(db[0:hash.Size()], lHash)
	db[len(db)-len(msg)-1] = 1
	copy(db[len(db)-len(msg):], msg)

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

	mgf1XOR(db, hash, seed)
	mgf1XOR(seed, hash, db)

	m := new(big.Int)
	m.SetBytes(em)
	c := encrypt(new(big.Int), pub, m)
	out = c.Bytes()
	return
}
Beispiel #2
0
func (h *Hash) l3(m []byte, iter int) []byte {
	i := 0
	k1 := new(big.Int)
	k2 := new(big.Int)

	for need := iter + 1; need > 0; i++ {
		t := h.kdf(224, 128*(i+1))[16*i : 16*(i+1)]
		k1.SetBytes(t[:8])
		k2.SetBytes(t[8:])
		if k1.Cmp(p64) == -1 && k2.Cmp(p64) == -1 {
			need--
		}
	}

	mint := newInt(m)
	m1 := new(big.Int).Div(mint, p64p32)
	m2 := new(big.Int).Mod(mint, p64p32)

	y := new(big.Int).Add(m1, k1)
	y.Mul(y, new(big.Int).Add(m2, k2))
	y.Mod(y, p64)

	Y := make([]byte, 8)
	copy(Y[8-len(y.Bytes()):], y.Bytes())
	return Y
}
Beispiel #3
0
// Sign signs an arbitrary length hash (which should be the result of hashing a
// larger message) using the private key, priv. It returns the signature as a
// pair of integers. The security of the private key depends on the entropy of
// rand.
func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err os.Error) {
	// FIPS 186-3, section 4.6

	n := priv.Q.BitLen()
	if n&7 != 0 {
		err = InvalidPublicKeyError
		return
	}
	n >>= 3

	for {
		k := new(big.Int)
		buf := make([]byte, n)
		for {
			_, err = io.ReadFull(rand, buf)
			if err != nil {
				return
			}
			k.SetBytes(buf)
			if k.Sign() > 0 && k.Cmp(priv.Q) < 0 {
				break
			}
		}

		kInv := new(big.Int).ModInverse(k, priv.Q)

		r = new(big.Int).Exp(priv.G, k, priv.P)
		r.Mod(r, priv.Q)

		if r.Sign() == 0 {
			continue
		}

		if n > len(hash) {
			n = len(hash)
		}
		z := k.SetBytes(hash[:n])

		s = new(big.Int).Mul(priv.X, r)
		s.Add(s, z)
		s.Mod(s, priv.Q)
		s.Mul(s, kInv)
		s.Mod(s, priv.Q)

		if s.Sign() != 0 {
			break
		}
	}

	return
}
Beispiel #4
0
// parseBigInt treats the given bytes as a big-endian, signed integer and returns
// the result.
func parseBigInt(bytes []byte) *big.Int {
	ret := new(big.Int)
	if len(bytes) > 0 && bytes[0]&0x80 == 0x80 {
		// This is a negative number.
		notBytes := make([]byte, len(bytes))
		for i := range notBytes {
			notBytes[i] = ^bytes[i]
		}
		ret.SetBytes(notBytes)
		ret.Add(ret, bigOne)
		ret.Neg(ret)
		return ret
	}
	ret.SetBytes(bytes)
	return ret
}
Beispiel #5
0
// EncryptOAEP encrypts the given message with RSA-OAEP.
// The message must be no longer than the length of the public modulus less
// twice the hash length plus 2.
func EncryptOAEP(hash hash.Hash, random io.Reader, pub *PublicKey, msg []byte, label []byte) (out []byte, err error) {
	hash.Reset()
	k := (pub.N.BitLen() + 7) / 8
	if len(msg) > k-2*hash.Size()-2 {
		err = MessageTooLongError{}
		return
	}

	hash.Write(label)
	lHash := hash.Sum()
	hash.Reset()

	em := make([]byte, k)
	seed := em[1 : 1+hash.Size()]
	db := em[1+hash.Size():]

	copy(db[0:hash.Size()], lHash)
	db[len(db)-len(msg)-1] = 1
	copy(db[len(db)-len(msg):], msg)

	_, err = io.ReadFull(random, seed)
	if err != nil {
		return
	}

	mgf1XOR(db, hash, seed)
	mgf1XOR(seed, hash, db)

	m := new(big.Int)
	m.SetBytes(em)
	c := encrypt(new(big.Int), pub, m)
	out = c.Bytes()

	if len(out) < k {
		// If the output is too small, we need to left-pad with zeros.
		t := make([]byte, k)
		copy(t[k-len(out):], out)
		out = t
	}

	return
}
Beispiel #6
0
func B64ToBigInt(in string, b *big.Int) (err os.Error) {
	bsize := base64.StdEncoding.DecodedLen(len(in))
	buff := make([]byte, bsize)
	n, err := base64.StdEncoding.Decode(buff, bytes.NewBufferString(in).Bytes())
	neg := false
	if err == nil {
		buff = buff[0:n]
		if buff[0]&0x80 == 0x80 {
			neg = true
			buff[0] &= 0x7f
		}
		b.SetBytes(buff)
		// In case the passed in big was negative...
		b.Abs(b)
		if neg {
			b.Neg(b)
		}
	}
	return
}
Beispiel #7
0
// GenerateKey generates a public&private key pair. The Parameters of the
// PrivateKey must already be valid (see GenerateParameters).
func GenerateKey(priv *PrivateKey, rand io.Reader) os.Error {
	if priv.P == nil || priv.Q == nil || priv.G == nil {
		return os.ErrorString("crypto/dsa: parameters not set up before generating key")
	}

	x := new(big.Int)
	xBytes := make([]byte, priv.Q.BitLen()/8)

	for {
		_, err := io.ReadFull(rand, xBytes)
		if err != nil {
			return err
		}
		x.SetBytes(xBytes)
		if x.Sign() != 0 && x.Cmp(priv.Q) < 0 {
			break
		}
	}

	priv.X = x
	priv.Y = new(big.Int)
	priv.Y.Exp(priv.G, x, priv.P)
	return nil
}
Beispiel #8
0
// GenerateParameters puts a random, valid set of DSA parameters into params.
// This function takes many seconds, even on fast machines.
func GenerateParameters(params *Parameters, rand io.Reader, sizes ParameterSizes) (err os.Error) {
	// This function doesn't follow FIPS 186-3 exactly in that it doesn't
	// use a verification seed to generate the primes. The verification
	// seed doesn't appear to be exported or used by other code and
	// omitting it makes the code cleaner.

	var L, N int
	switch sizes {
	case L1024N160:
		L = 1024
		N = 160
	case L2048N224:
		L = 2048
		N = 224
	case L2048N256:
		L = 2048
		N = 256
	case L3072N256:
		L = 3072
		N = 256
	default:
		return os.ErrorString("crypto/dsa: invalid ParameterSizes")
	}

	qBytes := make([]byte, N/8)
	pBytes := make([]byte, L/8)

	q := new(big.Int)
	p := new(big.Int)
	rem := new(big.Int)
	one := new(big.Int)
	one.SetInt64(1)

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

		qBytes[len(qBytes)-1] |= 1
		qBytes[0] |= 0x80
		q.SetBytes(qBytes)

		if !big.ProbablyPrime(q, numMRTests) {
			continue
		}

		for i := 0; i < 4*L; i++ {
			_, err = io.ReadFull(rand, pBytes)
			if err != nil {
				return
			}

			pBytes[len(pBytes)-1] |= 1
			pBytes[0] |= 0x80

			p.SetBytes(pBytes)
			rem.Mod(p, q)
			rem.Sub(rem, one)
			p.Sub(p, rem)
			if p.BitLen() < L {
				continue
			}

			if !big.ProbablyPrime(p, numMRTests) {
				continue
			}

			params.P = p
			params.Q = q
			break GeneratePrimes
		}
	}

	h := new(big.Int)
	h.SetInt64(2)
	g := new(big.Int)

	pm1 := new(big.Int).Sub(p, one)
	e := new(big.Int).Div(pm1, q)

	for {
		g.Exp(h, e, p)
		if g.Cmp(one) == 0 {
			h.Add(h, one)
			continue
		}

		params.G = g
		return
	}

	panic("unreachable")
}