Skip to content

Commit

Permalink
Added random curve generator
Browse files Browse the repository at this point in the history
  • Loading branch information
Tatiana Bradley committed Oct 21, 2014
1 parent 009927b commit 139214d
Show file tree
Hide file tree
Showing 4 changed files with 193 additions and 0 deletions.
15 changes: 15 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
*.pyc
primecurves/build/lib/primecurves/primefieldelement.py
primecurves/build/lib/primecurves/bruteforcelog.py
primecurves/build/lib/primecurves/examples.py
primecurves/build/lib/primecurves/pollardsrho.py
primecurves/build/lib/primecurves/primecurve.py
primecurves/build/lib/primecurves/primepoint.py
primecurves/build/lib/primecurves/timer.py
primecurves/build/lib/primecurves/__init__.py
primecurves/dist/primecurves-0.1-py2.7.egg
primecurves/primecurves.egg-info/dependency_links.txt
primecurves/primecurves.egg-info/not-zip-safe
primecurves/primecurves.egg-info/PKG-INFO
primecurves/primecurves.egg-info/SOURCES.txt
primecurves/primecurves.egg-info/top_level.txt
81 changes: 81 additions & 0 deletions primecurves/primecurves/bitstring.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
"""
\file bitstring.py
\author Tatiana Bradley
\brief Class representing a bitstring.
"""
from random import *
import hashlib

class BitString:

""" CONSTRUCTOR """
def __init__(self, string):
self.string = string

"""
Constructor for a random string
"""
@classmethod
def random(cls, desiredLength):
result = "1"
for i in range(desiredLength - 1):
result += choice(["1", "0"])
return cls(result)

@classmethod
def fromInt(cls, integer, desiredLength):
return cls(bin(integer)[2:].zfill(desiredLength))

def __repr__(self):
return self.string

""" MEMBER FUNCTIONS """

def __iadd__(self, other):
self.string += other.string
return self

def length(self):
return len(self.string)

def toInt(self):
return int(self.string, 2)

def getHashedValue(self, hashFunction, hashLength):
hexDigest = hashFunction(self.string).hexdigest()
# Convert the digest to binary, with the correct length
return BitString(bin(int(hexDigest, 16))[2:].zfill(hashLength))

def setBit(self, index):
index = self.calculateIndex(index)
self.changeBit(index, "1")

def clearBit(self, index):
index = self.calculateIndex(index)
self.changeBit(index, "0")

def clearLeftBit(self):
self.clearBit(0)

def calculateIndex(self, index):
return len(self.string) - index - 1

def rightBits(self, numBits):
highestBit = self.calculateIndex(numBits - 1)
result = self.string[highestBit :]
return BitString(result)

def changeBit(self, index, newChar):
self.string = self.string[: index] + newChar + self.string[index + 1 :]












11 changes: 11 additions & 0 deletions primecurves/primecurves/examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,14 @@
K = PrimePoint(1974, 2248, E2)

INF = PrimePoint.inf() # the point at infinity

# Some PrimeFieldElements
zero = PrimeFieldElement(0, 5)
one = PrimeFieldElement(1, 5)
two = PrimeFieldElement(2, 5)
three = PrimeFieldElement(3, 5)
four = PrimeFieldElement(4, 5)

def runTest(r, a, b):
return r * (a ** 2) == b ** 3

86 changes: 86 additions & 0 deletions primecurves/primecurves/randomcurve.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
"""
\file randomcurve.py
\author Tatiana Bradley
\brief Generate (and verify) prime curves at random.
\detail Algorithms for random curve generation adapted
from Hankerson, Menezes and Vanstone (2004).
Uses SHA-256 hash function.
"""
from primecurves import *
from random import *
from math import *
from bitstring import *
import hashlib

BITS_IN_BYTE = 8
hashFunction = hashlib.sha256
HASH_LENGTH = hashFunction().digest_size * BITS_IN_BYTE

"""
" generateRandomCurve()
" INPUT: prime, a prime > 3.
" OUTPUT: a random seed
" a random curve over F_prime
"""
def generateRandomCurve(prime):
# STEP 1
t = long( ceil( log(prime, 2) ) )
s = t - 1
v = t - s * HASH_LENGTH

result = 0

while result == 0 or ((4 * result + 27) % prime) == 0:

# STEP 2
seedLength = HASH_LENGTH + 5
seed = BitString.random(seedLength)

# STEP 3
hashedSeed = seed.getHashedValue(hashFunction, HASH_LENGTH)
r0 = hashedSeed.rightBits(v)

# STEP 4
R0 = r0.clearLeftBit()

# STEP 5
seedAsInt = seed.toInt()

# STEP 6 and 7
binaryResult = BitString("")
for i in range(s):
rawString = BitString.fromInt((seedAsInt + i) % (2 ** seedLength), seedLength)
binaryResult += rawString.getHashedValue(hashFunction, HASH_LENGTH)

# STEP 8
result = binaryResult.toInt()

# STEP 9 (while loop condition)

# STEP 10
a, b = generateParameters(result, prime)

# STEP 11
return seed, PrimeCurve(a, b, prime)



""" HELPER FUNCTIONS """

"""
" Generate a, b such that
" r * b^2 = a^3 mod prime
"""
def generateParameters(r, prime):
found = False
while not found:
b = choice(range(prime))
for a in range(prime):
found = (r * (a ** 2)) % prime == (b ** 3) % prime
return a, b



# EXAMPLE:
Seed, Curve = generateRandomCurve(29)

0 comments on commit 139214d

Please sign in to comment.