func main() { pi := new(big.Int) pi.SetString("7199773997391911030609999317773941274322764333428698921736339643928346453700085358802973900485592910475480089726140708102474957429903531369589969318716771", 10) gi := new(big.Int) gi.SetString("4565356397095740655436854503483826832136106141639563487732438195343690437606117828318042418238184896212352329118608100083187535033402010599512641674644143", 10) q := new(big.Int) q.SetString("236234353446506858198510045061214171961", 10) G := dh.NewFiniteGroup(*pi) g := dh.NewFiniteElement(G, *gi) GG := dh.NewGeneratedGroup(G, g, *q) d := dh.NewDiffieHellman(GG) factors := dh.FindCoFactors(q, pi, G) moduli := make(map[int64]int64) total := big.NewInt(1) for factor, h := range factors { total.Mul(total, big.NewInt(factor)) mac := Bob(d, h) log.Printf("Guessing the shared secret in the subgroup of order %d", factor) found := false for i := int64(1); i <= factor; i++ { k := G.Pow(h, big.NewInt(i)) if hmac.Equal(mac, Sign(secretMessage, k)) { //log.Printf("%d^%d", elt, i) found = true moduli[factor] = i break } } if !found { panic("Could not guess the shared secret") } } // From Wikipedia CRT page x := new(big.Int) for n, a := range moduli { N := new(big.Int).Set(total) N.Div(N, big.NewInt(n)) N.ModInverse(N, big.NewInt(n)) N.Mul(N, total) N.Div(N, big.NewInt(n)) N.Mul(N, big.NewInt(a)) x.Add(x, N) x.Mod(x, total) } log.Printf("Predicted key: %d", x) log.Printf("%s", d) }
func main() { fmt.Printf("=== PHASE I: TEST ALGORITHM ===\n") pi := new(big.Int) pi.SetString("11470374874925275658116663507232161402086650258453896274534991676898999262641581519101074740642369848233294239851519212341844337347119899874391456329785623", 10) gi := new(big.Int) gi.SetString("622952335333961296978159266084741085889881358738459939978290179936063635566740258555167783009058567397963466103140082647486611657350811560630587013183357", 10) q := new(big.Int) q.SetString("335062023296420808191071248367701059461", 10) G := dh.NewFiniteGroup(*pi) g := dh.NewFiniteElement(G, *gi) GG := dh.NewGeneratedGroup(G, g, *q) targets := []string{ "7760073848032689505395005705677365876654629189298052775754597607446617558600394076764814236081991643094239886772481052254010323780165093955236429914607119", "9388897478013399550694114614498790691034187453089355259602614074132918843899833277397448144245883225611726912025846772975325932794909655215329941809013733", } hi := new(big.Int) a := 0 upperBounds := []int{1 << 20, 1 << 40} for i, hs := range targets { hi.SetString(hs, 10) b := upperBounds[i] h := dh.NewFiniteElement(G, *hi) log.Printf("Searching for discrete log of %s", h) x := dh.Pollard(GG, g, h, a, b) if x == nil { log.Printf("The wild kangaroo escaped!") } else { x.Mod(x, q) log.Printf("discrete log = %s", x) check := GG.Pow(g, x) log.Printf("%s^%d mod %s == %s", g, x, pi, GG.Pow(g, x)) if check.Cmp(h) != 0 { log.Printf("ERROR! Expected %s but got %s", h, check) } } } fmt.Printf("\n=== PHASE II: APPLY WITH COFACTOR ATTACK ===\n") factors := dh.FindCoFactors(q, pi, G) moduli := make(map[int64]int64) total := big.NewInt(1) d := dh.NewDiffieHellman(GG) for factor, h := range factors { total.Mul(total, big.NewInt(factor)) mac := Bob(d, h) log.Printf("Guessing the shared secret in the subgroup of order %d", factor) found := false for i := int64(1); i <= factor; i++ { k := G.Pow(h, big.NewInt(i)) if hmac.Equal(mac, Sign(secretMessage, k)) { //log.Printf("%d^%d", elt, i) found = true moduli[factor] = i break } } if !found { panic("Could not guess the shared secret") } } // From Wikipedia CRT page x := new(big.Int) for n, a := range moduli { N := new(big.Int).Set(total) N.Div(N, big.NewInt(n)) N.ModInverse(N, big.NewInt(n)) N.Mul(N, total) N.Div(N, big.NewInt(n)) N.Mul(N, big.NewInt(a)) x.Add(x, N) x.Mod(x, total) } log.Printf("x mod r = %s [r = %s]", x, total) n := new(big.Int) n.Sub(q, x) hp := GG.Op(d.PublicKey(), GG.Pow(g, n)) gp := GG.Pow(g, total) B := new(big.Int) B.Div(q, total) log.Printf("Searching for discrete log of %s", hp) m := dh.Pollard(GG, gp, hp, 0, int(B.Int64())) if m == nil { log.Printf("The wild kangaroo escaped!") } else { m.Mod(m, q) log.Printf("discrete log = %s", m) check := GG.Pow(gp, m) log.Printf("%s^%d mod %s == %s", gp, m, pi, GG.Pow(gp, m)) if check.Cmp(hp) != 0 { log.Printf("ERROR! Expected %s but got %s", hp, check) } } m.Mul(m, total) x.Add(x, m) log.Printf("Predicted key: %d", x) log.Printf("%s", d) }