package keys /* Keys: holding private and public keys */ import ( "fmt" "tools/common" "tools/rsa/integer" ) type private struct { p, q, b, d *integer.RSAInt } type public struct { N, E *integer.RSAInt } type Keys struct { *private *public base_init float64 base, exp int64 } func New(base_init float64, base, exp int64) (*Keys) { k := new(Keys) k.private = new(private) k.public = new(public) k.base_init, k.base, k.exp = base_init, base, exp return k } func (k *Keys) Private() *private { return k.private } func (k *Keys) Public() *public { return k.public } func (k *Keys) GenPrimes() { for k.Private().init(k); !k.Public().init(k); k.Private().init(k) {} k.Private().d.ModMulInv(k.Public().E, k.Private().b) } func (k *Keys) Crack() { _, k.Private().p, k.Private().q = k.Public().N.PollardPm1(2) fmt.Printf("p:%s\tq:%s\n", k.Private().p, k.Private().q) k.Private().b = k.Private().p.Copy().Mul(k.Private().q).EulerTot(k.Private().p, k.Private().q) k.Private().d.ModMulInv(k.Public().E, k.Public().N) } func (p *private) init(k *Keys) { p.p = integer.New( int64(k.base_init * float64(k.base), )).Mul( integer.New(k.base).Pow64( (k.exp / 2) - int64(common.IntLen(k.base)), ), ) p.q = p.p.Copy() p.genPQ() p.b = p.p.Copy().Mul(p.q).EulerTot(p.p, p.q) p.d = integer.New(0) } func (p *private) genPQ() { p.p.NextRandPrime() p.q.NextRandPrime() if p.p.Eq(p.q) { p.genPQ() } } func (p *public) init(k *Keys) bool { p.N = k.Private().p.Copy().Mul(k.Private().q) p.E = k.Private().b.Copy().RelativePrime() return p.testN(k) && p.E != nil } func (p *public) testN(k *Keys) bool { s := fmt.Sprintf("%d", int64(k.base_init * float64(k.base))) for i := int(0); i < int(k.exp) - common.IntLen(k.base); i++ { s += "0" } if t, e := integer.New(0).SetString(s); e { return p.N.Gt(t) } return false } func (k *Keys) SetKeys(d, e, n string) bool { k.Private().d = integer.New(0) k.Public().E = integer.New(0) k.Public().N = integer.New(0) _, d_success := k.Private().d.SetString(d) _, e_success := k.Public().E.SetString(e) _, n_success := k.Public().N.SetString(n) return d_success && e_success && n_success } func (p *private) D() *integer.RSAInt { return p.d } func (k *Keys) StrKeys() string { return fmt.Sprintf( "PRIVATE:\n\tp:%s\n\tq:%s\n\tb:%s\n\td:%s\nPUBLIC:\n\tn:%s\n\te:%s", k.Private().p, k.Private().q, k.Private().b, k.Private().d, k.Public().N, k.Public().E, ) }