mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-07-04 13:02:47 -05:00
numbertheory.py: generalise SqrtModP to do other roots.
I'm about to want to solve quartics mod a prime, which means I'll need to be able to take cube roots mod p as well as square roots. This commit introduces a more general class which can take rth roots for any prime r, and moreover, it can do it in a general cyclic group. (You have to tell it the group's order and give it some primitives for doing arithmetic, plus a way of iterating over the group elements that it can use to look for a non-rth-power and roots of unity.) That system makes it nicely easy to test, because you can give it a cyclic group represented as the integers under _addition_, and then you obviously know what all the right answers are. So I've also added a unit test system checking that.
This commit is contained in:
@ -111,9 +111,9 @@ class WeierstrassCurve(CurveBase):
|
||||
|
||||
def cpoint(self, x, yparity=0):
|
||||
if not hasattr(self, 'sqrtmodp'):
|
||||
self.sqrtmodp = SqrtModP(self.p)
|
||||
self.sqrtmodp = RootModP(2, self.p)
|
||||
rhs = x**3 + self.a.n * x + self.b.n
|
||||
y = self.sqrtmodp.sqrt(rhs)
|
||||
y = self.sqrtmodp.root(rhs)
|
||||
if (y - yparity) % 2:
|
||||
y = -y
|
||||
return self.point(x, y)
|
||||
@ -157,9 +157,9 @@ class MontgomeryCurve(CurveBase):
|
||||
|
||||
def cpoint(self, x, yparity=0):
|
||||
if not hasattr(self, 'sqrtmodp'):
|
||||
self.sqrtmodp = SqrtModP(self.p)
|
||||
self.sqrtmodp = RootModP(2, self.p)
|
||||
rhs = (x**3 + self.a.n * x**2 + x) / self.b
|
||||
y = self.sqrtmodp.sqrt(int(rhs))
|
||||
y = self.sqrtmodp.root(int(rhs))
|
||||
if (y - yparity) % 2:
|
||||
y = -y
|
||||
return self.point(x, y)
|
||||
@ -198,11 +198,11 @@ class TwistedEdwardsCurve(CurveBase):
|
||||
|
||||
def cpoint(self, y, xparity=0):
|
||||
if not hasattr(self, 'sqrtmodp'):
|
||||
self.sqrtmodp = SqrtModP(self.p)
|
||||
self.sqrtmodp = RootModP(self.p)
|
||||
y = ModP(self.p, y)
|
||||
y2 = y**2
|
||||
radicand = (y2 - 1) / (self.d * y2 - self.a)
|
||||
x = self.sqrtmodp.sqrt(radicand.n)
|
||||
x = self.sqrtmodp.root(radicand.n)
|
||||
if (x - xparity) % 2:
|
||||
x = -x
|
||||
return self.point(x, y)
|
||||
|
Reference in New Issue
Block a user