Decompose a number into 2 prime co-factors

前端 未结 2 1305
醉酒成梦
醉酒成梦 2021-01-21 08:06

One of the requirements for Telegram Authentication is decomposing a given number into 2 prime co-factors. In particular P*Q = N, where N < 2^63

How ca

2条回答
  •  庸人自扰
    2021-01-21 08:20

    Pollard's Rho Algorithm [VB.Net]

    Finds P very fast, where P*Q = N, for N < 2^63

    Dim rnd As New System.Random
    
    Function PollardRho(n As BigInteger) As BigInteger
        If n Mod 2 = 0 Then Return 2
    
        Dim x As BigInteger = rnd.Next(1, 1000)
        Dim c As BigInteger = rnd.Next(1, 1000)
        Dim g As BigInteger = 1
        Dim y = x
    
        While g = 1
            x = ((x * x) Mod n + c) Mod n
            y = ((y * y) Mod n + c) Mod n
            y = ((y * y) Mod n + c) Mod n
            g = gcd(BigInteger.Abs(x - y), n)
        End While
    
        Return g
    End Function
    
    Function gcd(a As BigInteger, b As BigInteger) As BigInteger
        Dim r As BigInteger
        While b <> 0
            r = a Mod b
            a = b
            b = r
        End While
        Return a
    End Function
    

    Richard Brent's Algorithm [VB.Net] This is even faster.

    Function Brent(n As BigInteger) As BigInteger
        If n Mod 2 = 0 Then Return 2
    
        Dim y As BigInteger = rnd.Next(1, 1000)
        Dim c As BigInteger = rnd.Next(1, 1000)
        Dim m As BigInteger = rnd.Next(1, 1000)
    
        Dim g As BigInteger = 1
        Dim r As BigInteger = 1
        Dim q As BigInteger = 1
    
        Dim x As BigInteger = 0
        Dim ys As BigInteger = 0
    
        While g = 1
            x = y
            For i = 1 To r
                y = ((y * y) Mod n + c) Mod n
            Next
            Dim k = New BigInteger(0)
            While (k < r And g = 1)
                ys = y
                For i = 1 To BigInteger.Min(m, r - k)
                    y = ((y * y) Mod n + c) Mod n
                    q = q * (BigInteger.Abs(x - y)) Mod n
                Next
    
                g = gcd(q, n)
                k = k + m
            End While
            r = r * 2
        End While
    
        If g = n Then
            While True
                ys = ((ys * ys) Mod n + c) Mod n
                g = gcd(BigInteger.Abs(x - ys), n)
                If g > 1 Then
                    Exit While
                End If
            End While
        End If
    
        Return g
    End Function
    

提交回复
热议问题