2012-12-19 14:49:40 -05:00

277 lines 9.2 KiB Python Raw Blame History

 ```import rsa ``` ```import hashlib ``` ```from struct import * ``` ``` ``` ```#There is another copy of this function in Bitmessagemain.py ``` ```def convertIntToString(n): ``` ``` a = __builtins__.hex(n) ``` ``` if a[-1:] == 'L': ``` ``` a = a[:-1] ``` ``` if (len(a) % 2) == 0: ``` ``` return a[2:].decode('hex') ``` ``` else: ``` ``` return ('0'+a[2:]).decode('hex') ``` ``` ``` ```ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" ``` ``` ``` ```def encodeBase58(num, alphabet=ALPHABET): ``` ``` """Encode a number in Base X ``` ``` ``` ``` `num`: The number to encode ``` ``` `alphabet`: The alphabet to use for encoding ``` ``` """ ``` ``` if (num == 0): ``` ``` return alphabet[0] ``` ``` arr = [] ``` ``` base = len(alphabet) ``` ``` while num: ``` ``` rem = num % base ``` ``` #print 'num is:', num ``` ``` num = num // base ``` ``` arr.append(alphabet[rem]) ``` ``` arr.reverse() ``` ``` return ''.join(arr) ``` ``` ``` ```def decodeBase58(string, alphabet=ALPHABET): ``` ``` """Decode a Base X encoded string into the number ``` ``` ``` ``` Arguments: ``` ``` - `string`: The encoded string ``` ``` - `alphabet`: The alphabet to use for encoding ``` ``` """ ``` ``` base = len(alphabet) ``` ``` strlen = len(string) ``` ``` num = 0 ``` ``` ``` ``` try: ``` ``` power = strlen - 1 ``` ``` for char in string: ``` ``` num += alphabet.index(char) * (base ** power) ``` ``` power -= 1 ``` ``` except: ``` ``` #character not found (like a space character or a 0) ``` ``` return 0 ``` ``` return num ``` ``` ``` ```def encodeVarint(integer): ``` ``` if integer < 0: ``` ``` print 'varint cannot be < 0' ``` ``` raise SystemExit ``` ``` if integer < 253: ``` ``` return pack('>B',integer) ``` ``` if integer >= 253 and integer < 65536: ``` ``` return pack('>B',253) + pack('>H',integer) ``` ``` if integer >= 65536 and integer < 4294967296: ``` ``` return pack('>B',254) + pack('>I',integer) ``` ``` if integer >= 4294967296 and integer < 18446744073709551616: ``` ``` return pack('>B',255) + pack('>Q',integer) ``` ``` if integer >= 18446744073709551616: ``` ``` print 'varint cannot be >= 18446744073709551616' ``` ``` raise SystemExit ``` ``` ``` ```def decodeVarint(data): ``` ``` if len(data) == 0: ``` ``` return (0,0) ``` ``` firstByte, = unpack('>B',data[0:1]) ``` ``` if firstByte < 253: ``` ``` return (firstByte,1) #the 1 is the length of the varint ``` ``` if firstByte == 253: ``` ``` a, = unpack('>H',data[1:3]) ``` ``` return (a,3) ``` ``` if firstByte == 254: ``` ``` a, = unpack('>I',data[1:5]) ``` ``` return (a,5) ``` ``` if firstByte == 255: ``` ``` a, = unpack('>Q',data[1:9]) ``` ``` return (a,9) ``` ``` ``` ``` ``` ``` ``` ```def calculateInventoryHash(data): ``` ``` sha = hashlib.new('sha512') ``` ``` sha2 = hashlib.new('sha512') ``` ``` sha.update(data) ``` ``` sha2.update(sha.digest()) ``` ``` return sha2.digest()[0:32] ``` ``` ``` ```def encodeAddress(version,stream,ripe): ``` ``` a = encodeVarint(version) + encodeVarint(stream) + ripe ``` ``` sha = hashlib.new('sha512') ``` ``` sha.update(a) ``` ``` currentHash = sha.digest() ``` ``` #print 'sha after first hashing: ', sha.hexdigest() ``` ``` sha = hashlib.new('sha512') ``` ``` sha.update(currentHash) ``` ``` #print 'sha after second hashing: ', sha.hexdigest() ``` ``` ``` ``` checksum = sha.digest()[0:4] ``` ``` #print 'len(a) = ', len(a) ``` ``` #print 'checksum = ', checksum.encode('hex') ``` ``` #print 'len(checksum) = ', len(checksum) ``` ``` ``` ``` asInt = int(a.encode('hex') + checksum.encode('hex'),16) ``` ``` #asInt = int(checksum.encode('hex') + a.encode('hex'),16) ``` ``` # print asInt ``` ``` return 'BM-'+ encodeBase58(asInt) ``` ``` ``` ```def decodeAddress(address): ``` ``` #returns (status, address version number, stream number, data (almost certainly a ripe hash)) ``` ``` ``` ``` """#check for the BM- at the front of the address. If it isn't there, this address might be for a different version of Bitmessage ``` ``` if address[:3] != 'BM-': ``` ``` status = 'missingbm' ``` ``` return status,0,0,0 ``` ``` #take off the BM- ``` ``` integer = decodeBase58(address[3:])""" ``` ``` ``` ``` #changed Bitmessage to accept addresses that lack the "BM-" prefix. ``` ``` if address[:3] == 'BM-': ``` ``` integer = decodeBase58(address[3:]) ``` ``` else: ``` ``` integer = decodeBase58(address) ``` ``` if integer == 0: ``` ``` status = 'invalidcharacters' ``` ``` return status,0,0,0 ``` ``` #after converting to hex, the string will be prepended with a 0x and appended with a L ``` ``` hexdata = hex(integer)[2:-1] ``` ``` ``` ``` if len(hexdata) % 2 != 0: ``` ``` hexdata = '0' + hexdata ``` ``` ``` ``` #print 'hexdata', hexdata ``` ``` ``` ``` data = hexdata.decode('hex') ``` ``` checksum = data[-4:] ``` ``` ``` ``` sha = hashlib.new('sha512') ``` ``` sha.update(data[:-4]) ``` ``` currentHash = sha.digest() ``` ``` #print 'sha after first hashing: ', sha.hexdigest() ``` ``` sha = hashlib.new('sha512') ``` ``` sha.update(currentHash) ``` ``` #print 'sha after second hashing: ', sha.hexdigest() ``` ``` ``` ``` if checksum != sha.digest()[0:4]: ``` ``` print 'checksum failed' ``` ``` status = 'checksumfailed' ``` ``` return status,0,0,0 ``` ``` #else: ``` ``` # print 'checksum PASSED' ``` ``` ``` ``` addressVersionNumber, bytesUsedByVersionNumber = decodeVarint(data[:9]) ``` ``` #print 'addressVersionNumber', addressVersionNumber ``` ``` #print 'bytesUsedByVersionNumber', bytesUsedByVersionNumber ``` ``` ``` ``` if addressVersionNumber < 1: ``` ``` print 'cannot decode version address version numbers this high' ``` ``` status = 'versiontoohigh' ``` ``` return status,0,0,0 ``` ``` ``` ``` streamNumber, bytesUsedByStreamNumber = decodeVarint(data[bytesUsedByVersionNumber:10+bytesUsedByVersionNumber]) ``` ``` #print streamNumber ``` ``` status = 'success' ``` ``` return status,addressVersionNumber,streamNumber,data[-24:-4] ``` ``` ``` ```def addBMIfNotPresent(address): ``` ``` if address[:3] != 'BM-': ``` ``` return 'BM-'+address ``` ``` else: ``` ``` return address ``` ``` ``` ```def addressStream(address): ``` ``` #returns the stream number of an address or False if there is a problem with the address. ``` ``` ``` ``` #check for the BM- at the front of the address. If it isn't there, this address might be for a different version of Bitmessage ``` ``` if address[:3] != 'BM-': ``` ``` status = 'missingbm' ``` ``` return False ``` ``` #here we take off the BM- ``` ``` integer = decodeBase58(address[3:]) ``` ``` #after converting to hex, the string will be prepended with a 0x and appended with a L ``` ``` hexdata = hex(integer)[2:-1] ``` ``` ``` ``` if len(hexdata) % 2 != 0: ``` ``` hexdata = '0' + hexdata ``` ``` ``` ``` #print 'hexdata', hexdata ``` ``` ``` ``` data = hexdata.decode('hex') ``` ``` checksum = data[-4:] ``` ``` ``` ``` sha = hashlib.new('sha512') ``` ``` sha.update(data[:-4]) ``` ``` currentHash = sha.digest() ``` ``` #print 'sha after first hashing: ', sha.hexdigest() ``` ``` sha = hashlib.new('sha512') ``` ``` sha.update(currentHash) ``` ``` #print 'sha after second hashing: ', sha.hexdigest() ``` ``` ``` ``` if checksum != sha.digest()[0:4]: ``` ``` print 'checksum failed' ``` ``` status = 'checksumfailed' ``` ``` return False ``` ``` #else: ``` ``` # print 'checksum PASSED' ``` ``` ``` ``` addressVersionNumber, bytesUsedByVersionNumber = decodeVarint(data[:9]) ``` ``` #print 'addressVersionNumber', addressVersionNumber ``` ``` #print 'bytesUsedByVersionNumber', bytesUsedByVersionNumber ``` ``` ``` ``` if addressVersionNumber < 1: ``` ``` print 'cannot decode version address version numbers this high' ``` ``` status = 'versiontoohigh' ``` ``` return False ``` ``` ``` ``` streamNumber, bytesUsedByStreamNumber = decodeVarint(data[bytesUsedByVersionNumber:9+bytesUsedByVersionNumber]) ``` ``` #print streamNumber ``` ``` status = 'success' ``` ``` return streamNumber ``` ``` ``` ``` ``` ```if __name__ == "__main__": ``` ``` #Let's make a new Bitmessage address: ``` ``` (pubkey, privkey) = rsa.newkeys(256) ``` ``` print privkey['n'] ``` ``` print privkey['e'] ``` ``` print privkey['d'] ``` ``` print privkey['p'] ``` ``` print privkey['q'] ``` ``` ``` ``` ripe = hashlib.new('ripemd160') ``` ``` sha = hashlib.new('sha512') ``` ``` sha.update(convertIntToString(pubkey.n)+convertIntToString(pubkey.e)) ``` ``` ``` ``` ripe.update(sha.digest()) ``` ``` #print 'sha digest:', sha.digest() ``` ``` #print 'ripe digest:', ripe.digest() ``` ``` #print len(sha.digest()) ``` ``` #print len(ripe.digest()) ``` ``` ``` ``` #prepend the version number and stream number ``` ``` a = '\x05' + '\x08' + ripe.digest() ``` ``` #print 'lengh of a at beginning = ', len(a) ``` ``` print 'This is the data to be encoded in the address: ', a.encode('hex') ``` ``` ``` ``` returnedAddress = encodeAddress(5,8,ripe.digest()) ``` ``` status,addressVersionNumber,streamNumber,data = decodeAddress(returnedAddress) ``` ``` print returnedAddress ``` ``` print 'Status:', status ``` ``` print 'addressVersionNumber', addressVersionNumber ``` ``` print 'streamNumber', streamNumber ``` ``` print 'length of data(the ripe hash):', len(data) ``` ``` ``` ``` print '\n\nNow let us try making an address with given 2048-bit n and e values.' ``` ``` testn = 16691381808213609635656612695328489234826227577985206736118595570304213887605602327717776979169783795560145663031146864154748634207927153095849203939039346778471192284119479329875655789428795925773927040539038073349089996911318012189546542694411685389074592231210678771416758973061752125295462189928432307067746658691146428088703129795340914596189054255127032271420140641112277113597275245807890920656563056790943850440012709593297328230145129809419550219898595770524436575484115680960823105256137731976622290028349172297572826751147335728017861413787053794003722218722212196385625462088929496952843002425059308041193 ``` ``` teste = 65537 ``` ``` ripe = hashlib.new('ripemd160') ``` ``` sha = hashlib.new('sha512') ``` ``` sha.update(convertIntToString(testn)+convertIntToString(teste)) ``` ``` ripe.update(sha.digest()) ``` ``` encodedAddress = encodeAddress(1,1,ripe.digest()) ``` ``` print encodedAddress ``` ``` status,addressVersionNumber,streamNumber,data = decodeAddress(encodedAddress) ``` ``` print 'Status:', status ``` ``` print 'addressVersionNumber', addressVersionNumber ``` ``` print 'streamNumber', streamNumber ``` ``` print 'length of data(the ripe hash):', len(data) ```