diff options
| author | Ondřej Surý <ondrej@sury.org> | 2011-09-13 13:11:55 +0200 | 
|---|---|---|
| committer | Ondřej Surý <ondrej@sury.org> | 2011-09-13 13:11:55 +0200 | 
| commit | 80f18fc933cf3f3e829c5455a1023d69f7b86e52 (patch) | |
| tree | 4b825dc642cb6eb9a060e54bf8d69288fbee4904 /src/pkg/crypto/dsa/dsa.go | |
| parent | 28592ee1ea1f5cdffcf85472f9de0285d928cf12 (diff) | |
| download | golang-80f18fc933cf3f3e829c5455a1023d69f7b86e52.tar.gz | |
Imported Upstream version 60
Diffstat (limited to 'src/pkg/crypto/dsa/dsa.go')
| -rw-r--r-- | src/pkg/crypto/dsa/dsa.go | 276 | 
1 files changed, 0 insertions, 276 deletions
| diff --git a/src/pkg/crypto/dsa/dsa.go b/src/pkg/crypto/dsa/dsa.go deleted file mode 100644 index a5f96fe94..000000000 --- a/src/pkg/crypto/dsa/dsa.go +++ /dev/null @@ -1,276 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package dsa implements the Digital Signature Algorithm, as defined in FIPS 186-3 -package dsa - -import ( -	"big" -	"io" -	"os" -) - -// Parameters represents the domain parameters for a key. These parameters can -// be shared across many keys. The bit length of Q must be a multiple of 8. -type Parameters struct { -	P, Q, G *big.Int -} - -// PublicKey represents a DSA public key. -type PublicKey struct { -	Parameters -	Y *big.Int -} - -// PrivateKey represents a DSA private key. -type PrivateKey struct { -	PublicKey -	X *big.Int -} - -type invalidPublicKeyError int - -func (invalidPublicKeyError) String() string { -	return "crypto/dsa: invalid public key" -} - -// InvalidPublicKeyError results when a public key is not usable by this code. -// FIPS is quite strict about the format of DSA keys, but other code may be -// less so. Thus, when using keys which may have been generated by other code, -// this error must be handled. -var InvalidPublicKeyError = invalidPublicKeyError(0) - -// ParameterSizes is a enumeration of the acceptable bit lengths of the primes -// in a set of DSA parameters. See FIPS 186-3, section 4.2. -type ParameterSizes int - -const ( -	L1024N160 ParameterSizes = iota -	L2048N224 -	L2048N256 -	L3072N256 -) - -// numMRTests is the number of Miller-Rabin primality tests that we perform. We -// pick the largest recommended number from table C.1 of FIPS 186-3. -const numMRTests = 64 - -// 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.NewError("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") -} - -// 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.NewError("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 -} - -// 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 -} - -// Verify verifies the signature in r, s of hash using the public key, pub. It -// returns true iff the signature is valid. -func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool { -	// FIPS 186-3, section 4.7 - -	if r.Sign() < 1 || r.Cmp(pub.Q) >= 0 { -		return false -	} -	if s.Sign() < 1 || s.Cmp(pub.Q) >= 0 { -		return false -	} - -	w := new(big.Int).ModInverse(s, pub.Q) - -	n := pub.Q.BitLen() -	if n&7 != 0 { -		return false -	} -	n >>= 3 - -	if n > len(hash) { -		n = len(hash) -	} -	z := new(big.Int).SetBytes(hash[:n]) - -	u1 := new(big.Int).Mul(z, w) -	u1.Mod(u1, pub.Q) -	u2 := w.Mul(r, w) -	u2.Mod(u2, pub.Q) -	v := u1.Exp(pub.G, u1, pub.P) -	u2.Exp(pub.Y, u2, pub.P) -	v.Mul(v, u2) -	v.Mod(v, pub.P) -	v.Mod(v, pub.Q) - -	return v.Cmp(r) == 0 -} | 
