📶 [WIP] RouterOS WinBox bruteforce
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
mtbf/curve.go

103 lines
3.0 KiB

package main
type WCurve struct {
p, r, a, b, h bigint
g *JacobiPoint
montA, conversionFromM bigint
conversion bigint
}
func newWCurve() *WCurve {
curve := WCurve{}
curve.p = NewBigintFromString("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed", 16)
curve.r = NewBigintFromString("1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed", 16)
curve.montA = NewBigintFromString("486662", 10)
curve.a = NewBigintFromString("2aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa984914a144", 16)
curve.b = NewBigintFromString("7b425ed097b425ed097b425ed097b425ed097b425ed097b4260b5e9c7710c864", 16)
curve.h = NewBigintFromString("8", 10)
curve.conversionFromM = curve.montA.Mul(modinv(NewBigint(3), curve.p)).Mod(curve.p)
curve.conversion = curve.p.Sub(curve.montA.Mul(modinv(NewBigint(3), curve.p))).Mod(curve.p)
curve.g = curve.liftX(NewBigint(9), false)
return &curve
}
func (curve *WCurve) Eq(other *WCurve) bool {
return curve.p.Eq(other.p) &&
curve.a.Mod(curve.p).Eq(other.a.Mod(curve.p)) &&
curve.b.Mod(curve.p).Eq(other.b.Mod(curve.p))
}
func (curve *WCurve) containsPoint(x, y bigint) bool {
p1 := x.Mul(x).Add(curve.a).Mul(x).Add(curve.b)
return y.Mul(y).Sub(p1).Mod(curve.p).EqInt(0)
}
func (curve *WCurve) genPublicKey(priv []byte) (pub []byte, parity bool) {
if len(priv) != 32 {
panic("invalid private key length")
}
p := NewBigintFromBytes(priv)
pt := curve.g.Mul(p)
return curve.toMontgomery(pt)
}
func (self *WCurve) toMontgomery(pt *JacobiPoint) (bytes []byte, parity bool) {
x := pt.AffineX().Add(self.conversion).Mod(self.p)
return x.ToBytes(32), pt.AffineY().AndInt(1).EqInt(1)
}
func (self *WCurve) liftX(x bigint, parity bool) *JacobiPoint {
x = x.Mod(self.p)
ySquared := x.Mul(x).Mul(x).Add(self.montA.Mul(x).Mul(x).Add(x)).Mod(self.p)
x = x.Add(self.conversionFromM).Mod(self.p)
ys0, ys1 := primeModSqrt(ySquared, self.p)
if ys0.Empty() && ys1.Empty() {
return nil
} else {
pt1 := NewJacobiPoint(self, x, ys0, NewBigint(1), self.r)
pt2 := NewJacobiPoint(self, x, ys1, NewBigint(1), self.r)
if pt1.AffineY().AndInt(1).EqInt(1) && parity {
return pt1
} else if pt2.AffineY().AndInt(1).EqInt(1) && parity {
return pt2
} else if pt1.AffineY().AndInt(1).EqInt(0) && !parity {
return pt1
} else {
return pt2
}
}
}
func (self *WCurve) redp1(bytes []byte, parity bool) *JacobiPoint {
x := getSHA2Digest(bytes)
for {
x2 := getSHA2Digest(x)
pt := self.liftX(NewBigintFromBytes(x2), parity)
if pt == nil {
x = NewBigintFromBytes(x).AddInt(1).ToBytes(32)
} else {
return pt
}
}
}
func (self *WCurve) check(a *JacobiPoint) bool {
ax := a.AffineX()
ay := a.AffineY()
left := ay.Mul(ay).Mod(self.p)
right := ax.Mul(ax).Mul(ax).Add(self.a.Mul(ax)).Add(self.b).Mod(self.p)
return left.Eq(right)
}
func (self *WCurve) multiplyByG(a bigint) *JacobiPoint {
return self.g.Mul(a)
}
func (self *WCurve) finiteFieldValue(a bigint) bigint {
return a.Mod(self.r)
}