...

Source file src/crypto/dsa/dsa.go

Documentation: crypto/dsa

     1  // Copyright 2011 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Package dsa implements the Digital Signature Algorithm, as defined in FIPS 186-3.
     6  //
     7  // The DSA operations in this package are not implemented using constant-time algorithms.
     8  //
     9  // Deprecated: DSA is a legacy algorithm, and modern alternatives such as
    10  // Ed25519 (implemented by package crypto/ed25519) should be used instead. Keys
    11  // with 1024-bit moduli (L1024N160 parameters) are cryptographically weak, while
    12  // bigger keys are not widely supported. Note that FIPS 186-5 no longer approves
    13  // DSA for signature generation.
    14  package dsa
    15  
    16  import (
    17  	"errors"
    18  	"io"
    19  	"math/big"
    20  
    21  	"crypto/internal/randutil"
    22  )
    23  
    24  // Parameters represents the domain parameters for a key. These parameters can
    25  // be shared across many keys. The bit length of Q must be a multiple of 8.
    26  type Parameters struct {
    27  	P, Q, G *big.Int
    28  }
    29  
    30  // PublicKey represents a DSA public key.
    31  type PublicKey struct {
    32  	Parameters
    33  	Y *big.Int
    34  }
    35  
    36  // PrivateKey represents a DSA private key.
    37  type PrivateKey struct {
    38  	PublicKey
    39  	X *big.Int
    40  }
    41  
    42  // ErrInvalidPublicKey results when a public key is not usable by this code.
    43  // FIPS is quite strict about the format of DSA keys, but other code may be
    44  // less so. Thus, when using keys which may have been generated by other code,
    45  // this error must be handled.
    46  var ErrInvalidPublicKey = errors.New("crypto/dsa: invalid public key")
    47  
    48  // ParameterSizes is an enumeration of the acceptable bit lengths of the primes
    49  // in a set of DSA parameters. See FIPS 186-3, section 4.2.
    50  type ParameterSizes int
    51  
    52  const (
    53  	L1024N160 ParameterSizes = iota
    54  	L2048N224
    55  	L2048N256
    56  	L3072N256
    57  )
    58  
    59  // numMRTests is the number of Miller-Rabin primality tests that we perform. We
    60  // pick the largest recommended number from table C.1 of FIPS 186-3.
    61  const numMRTests = 64
    62  
    63  // GenerateParameters puts a random, valid set of DSA parameters into params.
    64  // This function can take many seconds, even on fast machines.
    65  func GenerateParameters(params *Parameters, rand io.Reader, sizes ParameterSizes) error {
    66  	// This function doesn't follow FIPS 186-3 exactly in that it doesn't
    67  	// use a verification seed to generate the primes. The verification
    68  	// seed doesn't appear to be exported or used by other code and
    69  	// omitting it makes the code cleaner.
    70  
    71  	var L, N int
    72  	switch sizes {
    73  	case L1024N160:
    74  		L = 1024
    75  		N = 160
    76  	case L2048N224:
    77  		L = 2048
    78  		N = 224
    79  	case L2048N256:
    80  		L = 2048
    81  		N = 256
    82  	case L3072N256:
    83  		L = 3072
    84  		N = 256
    85  	default:
    86  		return errors.New("crypto/dsa: invalid ParameterSizes")
    87  	}
    88  
    89  	qBytes := make([]byte, N/8)
    90  	pBytes := make([]byte, L/8)
    91  
    92  	q := new(big.Int)
    93  	p := new(big.Int)
    94  	rem := new(big.Int)
    95  	one := new(big.Int)
    96  	one.SetInt64(1)
    97  
    98  GeneratePrimes:
    99  	for {
   100  		if _, err := io.ReadFull(rand, qBytes); err != nil {
   101  			return err
   102  		}
   103  
   104  		qBytes[len(qBytes)-1] |= 1
   105  		qBytes[0] |= 0x80
   106  		q.SetBytes(qBytes)
   107  
   108  		if !q.ProbablyPrime(numMRTests) {
   109  			continue
   110  		}
   111  
   112  		for i := 0; i < 4*L; i++ {
   113  			if _, err := io.ReadFull(rand, pBytes); err != nil {
   114  				return err
   115  			}
   116  
   117  			pBytes[len(pBytes)-1] |= 1
   118  			pBytes[0] |= 0x80
   119  
   120  			p.SetBytes(pBytes)
   121  			rem.Mod(p, q)
   122  			rem.Sub(rem, one)
   123  			p.Sub(p, rem)
   124  			if p.BitLen() < L {
   125  				continue
   126  			}
   127  
   128  			if !p.ProbablyPrime(numMRTests) {
   129  				continue
   130  			}
   131  
   132  			params.P = p
   133  			params.Q = q
   134  			break GeneratePrimes
   135  		}
   136  	}
   137  
   138  	h := new(big.Int)
   139  	h.SetInt64(2)
   140  	g := new(big.Int)
   141  
   142  	pm1 := new(big.Int).Sub(p, one)
   143  	e := new(big.Int).Div(pm1, q)
   144  
   145  	for {
   146  		g.Exp(h, e, p)
   147  		if g.Cmp(one) == 0 {
   148  			h.Add(h, one)
   149  			continue
   150  		}
   151  
   152  		params.G = g
   153  		return nil
   154  	}
   155  }
   156  
   157  // GenerateKey generates a public&private key pair. The Parameters of the
   158  // [PrivateKey] must already be valid (see [GenerateParameters]).
   159  func GenerateKey(priv *PrivateKey, rand io.Reader) error {
   160  	if priv.P == nil || priv.Q == nil || priv.G == nil {
   161  		return errors.New("crypto/dsa: parameters not set up before generating key")
   162  	}
   163  
   164  	x := new(big.Int)
   165  	xBytes := make([]byte, priv.Q.BitLen()/8)
   166  
   167  	for {
   168  		_, err := io.ReadFull(rand, xBytes)
   169  		if err != nil {
   170  			return err
   171  		}
   172  		x.SetBytes(xBytes)
   173  		if x.Sign() != 0 && x.Cmp(priv.Q) < 0 {
   174  			break
   175  		}
   176  	}
   177  
   178  	priv.X = x
   179  	priv.Y = new(big.Int)
   180  	priv.Y.Exp(priv.G, x, priv.P)
   181  	return nil
   182  }
   183  
   184  // fermatInverse calculates the inverse of k in GF(P) using Fermat's method.
   185  // This has better constant-time properties than Euclid's method (implemented
   186  // in math/big.Int.ModInverse) although math/big itself isn't strictly
   187  // constant-time so it's not perfect.
   188  func fermatInverse(k, P *big.Int) *big.Int {
   189  	two := big.NewInt(2)
   190  	pMinus2 := new(big.Int).Sub(P, two)
   191  	return new(big.Int).Exp(k, pMinus2, P)
   192  }
   193  
   194  // Sign signs an arbitrary length hash (which should be the result of hashing a
   195  // larger message) using the private key, priv. It returns the signature as a
   196  // pair of integers. The security of the private key depends on the entropy of
   197  // rand.
   198  //
   199  // Note that FIPS 186-3 section 4.6 specifies that the hash should be truncated
   200  // to the byte-length of the subgroup. This function does not perform that
   201  // truncation itself.
   202  //
   203  // Be aware that calling Sign with an attacker-controlled [PrivateKey] may
   204  // require an arbitrary amount of CPU.
   205  func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err error) {
   206  	randutil.MaybeReadByte(rand)
   207  
   208  	// FIPS 186-3, section 4.6
   209  
   210  	n := priv.Q.BitLen()
   211  	if priv.Q.Sign() <= 0 || priv.P.Sign() <= 0 || priv.G.Sign() <= 0 || priv.X.Sign() <= 0 || n%8 != 0 {
   212  		err = ErrInvalidPublicKey
   213  		return
   214  	}
   215  	n >>= 3
   216  
   217  	var attempts int
   218  	for attempts = 10; attempts > 0; attempts-- {
   219  		k := new(big.Int)
   220  		buf := make([]byte, n)
   221  		for {
   222  			_, err = io.ReadFull(rand, buf)
   223  			if err != nil {
   224  				return
   225  			}
   226  			k.SetBytes(buf)
   227  			// priv.Q must be >= 128 because the test above
   228  			// requires it to be > 0 and that
   229  			//    ceil(log_2(Q)) mod 8 = 0
   230  			// Thus this loop will quickly terminate.
   231  			if k.Sign() > 0 && k.Cmp(priv.Q) < 0 {
   232  				break
   233  			}
   234  		}
   235  
   236  		kInv := fermatInverse(k, priv.Q)
   237  
   238  		r = new(big.Int).Exp(priv.G, k, priv.P)
   239  		r.Mod(r, priv.Q)
   240  
   241  		if r.Sign() == 0 {
   242  			continue
   243  		}
   244  
   245  		z := k.SetBytes(hash)
   246  
   247  		s = new(big.Int).Mul(priv.X, r)
   248  		s.Add(s, z)
   249  		s.Mod(s, priv.Q)
   250  		s.Mul(s, kInv)
   251  		s.Mod(s, priv.Q)
   252  
   253  		if s.Sign() != 0 {
   254  			break
   255  		}
   256  	}
   257  
   258  	// Only degenerate private keys will require more than a handful of
   259  	// attempts.
   260  	if attempts == 0 {
   261  		return nil, nil, ErrInvalidPublicKey
   262  	}
   263  
   264  	return
   265  }
   266  
   267  // Verify verifies the signature in r, s of hash using the public key, pub. It
   268  // reports whether the signature is valid.
   269  //
   270  // Note that FIPS 186-3 section 4.6 specifies that the hash should be truncated
   271  // to the byte-length of the subgroup. This function does not perform that
   272  // truncation itself.
   273  func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool {
   274  	// FIPS 186-3, section 4.7
   275  
   276  	if pub.P.Sign() == 0 {
   277  		return false
   278  	}
   279  
   280  	if r.Sign() < 1 || r.Cmp(pub.Q) >= 0 {
   281  		return false
   282  	}
   283  	if s.Sign() < 1 || s.Cmp(pub.Q) >= 0 {
   284  		return false
   285  	}
   286  
   287  	w := new(big.Int).ModInverse(s, pub.Q)
   288  	if w == nil {
   289  		return false
   290  	}
   291  
   292  	n := pub.Q.BitLen()
   293  	if n%8 != 0 {
   294  		return false
   295  	}
   296  	z := new(big.Int).SetBytes(hash)
   297  
   298  	u1 := new(big.Int).Mul(z, w)
   299  	u1.Mod(u1, pub.Q)
   300  	u2 := w.Mul(r, w)
   301  	u2.Mod(u2, pub.Q)
   302  	v := u1.Exp(pub.G, u1, pub.P)
   303  	u2.Exp(pub.Y, u2, pub.P)
   304  	v.Mul(v, u2)
   305  	v.Mod(v, pub.P)
   306  	v.Mod(v, pub.Q)
   307  
   308  	return v.Cmp(r) == 0
   309  }
   310  

View as plain text