From a7ee29df8eb6c4376624c4111d161feffacbd401 Mon Sep 17 00:00:00 2001 From: filifa Date: Wed, 20 Aug 2025 00:51:51 -0400 Subject: [PATCH] implement -t flag --- cmd/primitiveRoot.go | 45 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/cmd/primitiveRoot.go b/cmd/primitiveRoot.go index 63162cd..49443ee 100644 --- a/cmd/primitiveRoot.go +++ b/cmd/primitiveRoot.go @@ -73,8 +73,44 @@ func computeNaive(modulus *big.Int) (*big.Int, error) { return nil, errors.New("no primitive root") } -func computeFromFactors(modulus *big.Int, tpf []string) *big.Int { - return nil +func computeFromFactors(modulus *big.Int, tpf []string) (*big.Int, error) { + phi := big.NewInt(1) + factors := make(map[string]bool) + for _, s := range tpf { + p, ok := new(big.Int).SetString(s, 10) + if !ok { + return nil, errors.New("invalid input " + s) + } + + phi.Mul(phi, p) + factors[p.Text(10)] = true + } + + for g := big.NewInt(1); g.Cmp(modulus) == -1; g.Add(g, big.NewInt(1)) { + gcd := new(big.Int).GCD(nil, nil, g, modulus) + if gcd.Cmp(big.NewInt(1)) != 0 { + continue + } + + isPrimitive := true + for p := range factors { + e := new(big.Int) + f, _ := new(big.Int).SetString(p, 10) + k := new(big.Int).Div(phi, f) + e.Exp(g, k, modulus) + + if e.Cmp(big.NewInt(1)) == 0 { + isPrimitive = false + break + } + } + + if isPrimitive { + return g, nil + } + } + + return nil, errors.New("no primitive root") } func primitiveRoot(cmd *cobra.Command, args []string) { @@ -91,7 +127,10 @@ func primitiveRoot(cmd *cobra.Command, args []string) { log.Fatal(err) } } else { - root = computeFromFactors(m, tpf) + root, err = computeFromFactors(m, tpf) + if err != nil { + log.Fatal(err) + } } fmt.Println(root)