diff --git a/cmd/primitiveRoot.go b/cmd/primitiveRoot.go index 329415a..a721f39 100644 --- a/cmd/primitiveRoot.go +++ b/cmd/primitiveRoot.go @@ -29,15 +29,34 @@ var modulus string var tpf []string func totient(n *big.Int) *big.Int { - total := big.NewInt(0) - for a := big.NewInt(1); a.Cmp(n) == -1; a.Add(a, big.NewInt(1)) { - gcd := new(big.Int).GCD(nil, nil, a, n) - if gcd.Cmp(big.NewInt(1)) == 0 { - total.Add(total, big.NewInt(1)) + N := new(big.Int).Set(n) + + phi := new(big.Int).Set(N) + + sqrtn := new(big.Int).Sqrt(N) + for i := big.NewInt(2); i.Cmp(sqrtn) != 1; i.Add(i, big.NewInt(1)) { + mod := new(big.Int).Mod(N, i) + if mod.Cmp(big.NewInt(0)) != 0 { + continue + } + + // phi -= phi // i + tmp := new(big.Int).Div(phi, i) + phi.Sub(phi, tmp) + + for mod.Cmp(big.NewInt(0)) == 0 { + N.Div(N, i) + mod.Mod(N, i) } } - return total + if N.Cmp(big.NewInt(1)) == 1 { + // phi -= phi // N + tmp := new(big.Int).Div(phi, N) + phi.Sub(phi, tmp) + } + + return phi } func multiplicativeOrder(g *big.Int, modulus *big.Int) *big.Int {