RSA-704 "Lottery" Script
Since I found out that RSA-640 was solved, I've been thinking about altering my script for RSA-704. I made a number of changes:
- Focusing on generating binary numbers with exactly half the digits of RSA-704. Both RSA-640 and RSA-576's factors had that property.
- Used join() to concatenate the binary number string elements instead of +='s.
- Used Python's native base-10 conversion instead of baseconvert.
- Decided to calculate the primes below 2000 and check these against the generated number, since that might save compute cycles versus trying every number against RSA-704. It seems like it makes things go faster.
- Improved the output.
Here it is: download text version
#!/usr/bin/env python
# rsa-704-rand.py:
# RSA-704 Factoring Challenge "Lottery Solution" by Alex Harden
# Version 1.0: 05-Apr-2006
# Copyright (C) 2003,2006 Alex Harden (http://alexharden.org/blog/)
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# Find the GPL online at: http://www.gnu.org/copyleft/gpl.html
# Info about the RSA Challenge Numbers:
# http://www.rsasecurity.com/rsalabs/challenges/factoring/numbers.html
# Interesting fact about the solutions to the RSA-576 and RSA-640
# challenges: both factors were 50% of the number of digits of the
# challenge number's total digits. (Both binary and decimal.)
# RSA-576 numbers: for reference and testing:
# x=18819881292060796383869723946165043980716356337941738270076335642298885971\
# 5234665485319060606504743045317388011303396716199692321205734031879550656996\
# 221305168759307650257059L
# y=39807508642406493739712550055038649119906436234252670840638518957594638895\
# 7261768583317L
# z=47277214610743530253622307197304822463291469530209711645985217113052071125\
# 6363590397527L
# RSA-640 numbers:
# x=31074182404900437213507500358885679300373460228427275457201619488232064405\
# 1808150455634682967172328678243791627283803341547107310850191954852900733772\
# 4822783525742386454014691736602477652346609L
# y=16347336458092538484431338838650908598417836700330923121811108523893331001\
# 04508151212118167511579L
# z=19008712816648221131268515739354139754718967899685154936666385390880271038\
# 02104498957191261465571L
# For RSA-640 (193 digits), I concentrated on generating random odd numbers
# that had 96-98 digits (est. 319-321 binary digits). The solution numbers
# each had 97 digits and were each 320 binary digits (the middle of the
# estimated range).
# For RSA-704 (212 decimal digits), I'm concentrating on generating
# random odd numbers that have 352 binary digits. (106 decimal digits)
# Let's try to make likely prime numbers using a neat method:
# Reference 1: http://www.maths.abdn.ac.uk/~igc/tch/mx3015/notes/node157.html
# - create random bitstring of 352 binary digits (make first and last
# values "1")
# - convert it to decimal long int
# - if it's not divisible by any of the primes < 2000, see if it's a factor
# of RSA-704 (this step is optional - not sure how expensive the "z=x%n"
# actually is)
# Reference 2: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/162479
########################################
from random import seed, random
outfile='./rsa-704.txt' #if a factor is found, write it here
i=0
digits=352
N=2000
primes=[p for p in range(2,N) if 0 not in [p%d for d in range(2,p)]]
z=1
seed()
x=74037563479561712828046796097429573142593188889231289084936232638972765034028266276891996419625117843995894330502127585370118968098286733173273108930900552505116877063299072396380786710086096962537934650563796359L
while z <> 0 :
i+=1
slist=['1']
pos=1
while pos < digits-1 :
if round(random(),0) :
slist+='1'
else :
slist+='0'
pos+=1
slist+='1'
h="".join(slist)
n=long(h,2)
checkme=1
for p in primes :
if n%p == 0 :
checkme=0
break
if checkme :
z=x%n
if i%500 == 0 :
print 'i=',i
print 'n=',n
print 'z=',z
print '----------------'
if z == 0:
print 'found it'
print 'factor1=',n
print 'factor2=',x/n
print 'challenge=',x
file=open(outfile,'a+')
file.write(str(n))
file.write('\n')
file.close()
Comments
I've got a major speedup for you, if you're interested. The above code does about 40K tries per second on my 2GhZ; I was able to get it up to 1 million tries per second by substituting the following code: delete the following:
Posted by: Spot Toxic | April 7, 2006 2:36 PM
I also have a simpler variation that uses an implementation of Rabin-Miller algorithms I found on ASPN to try to generate large prime numbers, which I then try against RSA-704. I'll post that soon.
Posted by: aharden | April 7, 2006 7:37 PM
Posted by: aharden | April 7, 2006 8:35 PM
Otherwise, if I generate n random bits, and the first is zero, then I really have a number that is n-1 (or less) digits, because of the leading zero(s).
See, still have my matress, don't I?
I'll expect a 2% royalty when you win the prize. :)
Posted by: Honninscrave | April 10, 2006 10:20 AM
Posted by: aharden | April 10, 2006 4:34 PM