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)
}
func oddProduct(m, length uint64) *big.Int {
	switch length {
	case 1:
		return big.NewInt(int64(m))
	case 2:
		var mb big.Int
		mb.SetInt64(int64(m))
		mb2 := big.NewInt(int64(m - 2))
		return mb2.Mul(&mb, mb2)
	}
	hlen := length / 2
	h := oddProduct(m-hlen*2, length-hlen)
	return h.Mul(h, oddProduct(m, hlen))
}
func Product(seq []uint64) *big.Int {

	if len(seq) <= productSerialThreshold {
		var b big.Int
		sprod := big.NewInt(int64(seq[0]))
		for _, s := range seq[1:] {
			b.SetInt64(int64(s))
			sprod.Mul(sprod, &b)
		}
		return sprod
	}

	halfLen := len(seq) / 2
	lprod := Product(seq[0:halfLen])
	return lprod.Mul(lprod, Product(seq[halfLen:]))
}
Esempio n. 4
0
func NewInteger(arg Any) *Integer {
	var result big.Int
	switch arg.(type) {
	case int:
		result.SetInt64(int64(arg.(int)))
	case int64:
		result.SetInt64(arg.(int64))
	case uint64:
		result.SetString(strconv.Uitoa64(arg.(uint64)), 0)
	case string:
		result.SetString(arg.(string), 0)
	default:
		panic(fmt.Sprintf("Can not convert %T to Integer", arg))
	}
	return (*Integer)(&result)
}
func binomial(p *primes.Sieve, n, k uint64) *big.Int {

	var r big.Int
	if k > n {
		return &r
	}

	if k > n/2 {
		k = n - k
	}

	if k < 3 {
		switch k {
		case 0:
			return r.SetInt64(1)
		case 1:
			return r.SetInt64(int64(n))
		case 2:
			var n1 big.Int
			return r.Rsh(r.Mul(r.SetInt64(int64(n)), n1.SetInt64(int64(n-1))), 1)
		}
	}

	var i int
	rootN := xmath.FloorSqrt(n)
	factors := make([]uint64, n)

	p.IteratePrimes(2, rootN, func(p uint64) {
		var r, nn, kk uint64 = 0, n, k
		for nn > 0 {
			if nn%p < kk%p+r {
				r = 1
				factors[i] = p
				i++
			} else {
				r = 0
			}
			nn /= p
			kk /= p
		}
	})

	p.IteratePrimes(rootN+1, n/2, func(p uint64) {
		if n%p < k%p {
			factors[i] = p
			i++
		}
	})

	p.IteratePrimes(n-k+1, n, func(p uint64) {
		factors[i] = p
		i++
	})

	return xmath.Product(factors[0:i])
}
func (s *Sieve) Primorial(lo, hi uint64) *big.Int {

	if lo > hi {
		return big.NewInt(1)
	}

	if hi-lo < 200 {
		var r, t big.Int
		r.SetInt64(1)
		s.IteratePrimes(lo, hi, func(prime uint64) {
			r.Mul(&r, t.SetInt64(int64(prime)))
			return
		})
		return &r
	}

	h := (lo + hi) / 2
	r := s.Primorial(lo, h)

	return r.Mul(r, s.Primorial(h+1, hi))
}
Esempio n. 7
0
func testParameterGeneration(t *testing.T, sizes ParameterSizes, L, N int) {
	var priv PrivateKey
	params := &priv.Parameters

	err := GenerateParameters(params, rand.Reader, sizes)
	if err != nil {
		t.Errorf("%d: %s", int(sizes), err)
		return
	}

	if params.P.BitLen() != L {
		t.Errorf("%d: params.BitLen got:%d want:%d", int(sizes), params.P.BitLen(), L)
	}

	if params.Q.BitLen() != N {
		t.Errorf("%d: q.BitLen got:%d want:%d", int(sizes), params.Q.BitLen(), L)
	}

	one := new(big.Int)
	one.SetInt64(1)
	pm1 := new(big.Int).Sub(params.P, one)
	quo, rem := new(big.Int).DivMod(pm1, params.Q, new(big.Int))
	if rem.Sign() != 0 {
		t.Errorf("%d: p-1 mod q != 0", int(sizes))
	}
	x := new(big.Int).Exp(params.G, quo, params.P)
	if x.Cmp(one) == 0 {
		t.Errorf("%d: invalid generator", int(sizes))
	}

	err = GenerateKey(&priv, rand.Reader)
	if err != nil {
		t.Errorf("error generating key: %s", err)
		return
	}

	testSignAndVerify(t, int(sizes), &priv)
}
func Factorial(n uint64) (r *big.Int) {
	var oddFactNDiv2, oddFactNDiv4 big.Int

	// closes on oddFactNDiv2, oddFactNDiv4
	oddSwing := func(n uint64) (r *big.Int) {

		if n < uint64(len(smallOddSwing)) {
			return big.NewInt(smallOddSwing[n])
		}

		length := (n - 1) / 4
		if n%4 != 2 {
			length++
		}
		high := n - (n+1)&1
		ndiv4 := n / 4

		var oddFact big.Int
		if ndiv4 < uint64(len(smallOddFactorial)) {
			oddFact.SetInt64(smallOddFactorial[ndiv4])
			r = &oddFact
		} else {
			r = &oddFactNDiv4
		}

		return oddFact.Quo(oddProduct(high, length), r)
	}

	// closes on oddFactNDiv2, oddFactNDiv4, oddSwing, and itself
	var oddFactorial func(uint64) *big.Int
	oddFactorial = func(n uint64) (oddFact *big.Int) {
		if n < uint64(len(smallOddFactorial)) {
			oddFact = big.NewInt(smallOddFactorial[n])
		} else {
			oddFact = oddFactorial(n / 2)
			oddFact.Mul(oddFact.Mul(oddFact, oddFact), oddSwing(n))
		}

		oddFactNDiv4.Set(&oddFactNDiv2)
		oddFactNDiv2.Set(oddFact)
		return oddFact
	}

	oddFactNDiv2.SetInt64(1)
	oddFactNDiv4.SetInt64(1)
	r = oddFactorial(n)
	exp := uint(n - uint64(xmath.BitCount64(n)))
	return r.Lsh(r, exp)
}
Esempio n. 9
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")
}
func main() {
	// integer
	is := "1234"
	fmt.Println("original:   ", is)
	i, err := strconv.Atoi(is)
	if err != nil {
		fmt.Println(err)
		return
	}
	// assignment back to original variable shows result is the same type.
	is = strconv.Itoa(i + 1)
	fmt.Println("incremented:", is)

	// error checking worthwhile
	fmt.Println()
	_, err = strconv.Atoi(" 1234") // whitespace not allowed
	fmt.Println(err)
	_, err = strconv.Atoi("12345678901")
	fmt.Println(err)
	_, err = strconv.Atoi("_1234")
	fmt.Println(err)
	_, err = strconv.Atof64("12.D34")
	fmt.Println(err)

	// float
	fmt.Println()
	fs := "12.34"
	fmt.Println("original:   ", fs)
	f, err := strconv.Atof64(fs)
	if err != nil {
		fmt.Println(err)
		return
	}
	// various options on Ftoa64 produce different formats.  All are valid
	// input to Atof64, so result format does not have to match original
	// format.  (Matching original format would take a lot of code.)
	fs = strconv.Ftoa64(f+1, 'g', -1)
	fmt.Println("incremented:", fs)
	fs = strconv.Ftoa64(f+1, 'e', 4)
	fmt.Println("what format?", fs)

	// complex
	// strconv package doesn't handle complex types, but fmt does.
	// (fmt can be used on ints and floats too, but strconv is more efficient.)
	fmt.Println()
	cs := "(12+34i)"
	fmt.Println("original:   ", cs)
	var c complex128
	_, err = fmt.Sscan(cs, &c)
	if err != nil {
		fmt.Println(err)
		return
	}
	cs = fmt.Sprint(c + 1)
	fmt.Println("incremented:", cs)

	// big integers have their own functions
	fmt.Println()
	bs := "170141183460469231731687303715884105728"
	fmt.Println("original:   ", bs)
	var b, one big.Int
	_, ok := b.SetString(bs, 10)
	if !ok {
		fmt.Println("big.SetString fail")
		return
	}
	one.SetInt64(1)
	bs = b.Add(&b, &one).String()
	fmt.Println("incremented:", bs)
}