Beispiel #1
0
// Int returns a uniform random value in [0, max).
func Int(rand io.Reader, max *big.Int) (n *big.Int, err error) {
	k := (max.BitLen() + 7) / 8

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

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

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

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

		n.SetBytes(bytes)
		if n.Cmp(max) < 0 {
			return
		}
	}

	return
}
func info(a *big.Int, n uint) {
	dtrunc := int64(float64(a.BitLen())*.30103) - 10
	var first, rest big.Int
	rest.Exp(first.SetInt64(10), rest.SetInt64(dtrunc), nil)
	first.Quo(a, &rest)
	fstr := first.String()
	fmt.Printf("%d! begins %s... and has %d digits.\n",
		n, fstr, int64(len(fstr))+dtrunc)
}
Beispiel #3
0
func intLength(n *big.Int) int {
	length := 4 /* length bytes */
	if n.Sign() < 0 {
		nMinus1 := new(big.Int).Neg(n)
		nMinus1.Sub(nMinus1, bigOne)
		bitLen := nMinus1.BitLen()
		if bitLen%8 == 0 {
			// The number will need 0xff padding
			length++
		}
		length += (bitLen + 7) / 8
	} else if n.Sign() == 0 {
		// A zero is the zero length string
	} else {
		bitLen := n.BitLen()
		if bitLen%8 == 0 {
			// The number will need 0x00 padding
			length++
		}
		length += (bitLen + 7) / 8
	}

	return length
}
Beispiel #4
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")
}
Beispiel #5
0
// writeBig serializes a *big.Int to w.
func writeBig(w io.Writer, i *big.Int) os.Error {
	return writeMPI(w, uint16(i.BitLen()), i.Bytes())
}
Beispiel #6
0
func fromBig(n *big.Int) parsedMPI {
	return parsedMPI{
		bytes:     n.Bytes(),
		bitLength: uint16(n.BitLen()),
	}
}
Beispiel #7
0
// mpiLength returns the length of the given *big.Int when serialized as an
// MPI.
func mpiLength(n *big.Int) (mpiLengthInBytes int) {
	mpiLengthInBytes = 2 /* MPI length */
	mpiLengthInBytes += (n.BitLen() + 7) / 8
	return
}