From d19d35c4d443fc2c4c65ccd680e3f0d0342e96c0 Mon Sep 17 00:00:00 2001 From: Dominik Roth Date: Thu, 25 Jun 2020 11:44:13 +0200 Subject: [PATCH] off to a new start... --- __pycache__/lazarus.cpython-38.pyc | Bin 0 -> 5418 bytes __pycache__/main.cpython-36.pyc | Bin 17650 -> 0 bytes bethany.py | 87 ++++++++++++++ break.py | 180 ----------------------------- lazarus.py | 146 ++++++++++++++++------- lazarus.pyc | Bin 2768 -> 0 bytes note.py | 48 -------- 7 files changed, 191 insertions(+), 270 deletions(-) create mode 100644 __pycache__/lazarus.cpython-38.pyc delete mode 100644 __pycache__/main.cpython-36.pyc create mode 100644 bethany.py delete mode 100644 break.py delete mode 100644 lazarus.pyc delete mode 100644 note.py diff --git a/__pycache__/lazarus.cpython-38.pyc b/__pycache__/lazarus.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b796df8734c4d85972d78fbd3e8268e601da90ae GIT binary patch literal 5418 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 literal 0 HcmV?d00001 diff --git a/__pycache__/main.cpython-36.pyc b/__pycache__/main.cpython-36.pyc deleted file mode 100644 index 44726a1b28fcd3aa2ff929d3af8dbd1f2d780d06..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17650 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 diff --git a/bethany.py b/bethany.py new file mode 100644 index 0000000..f097641 --- /dev/null +++ b/bethany.py @@ -0,0 +1,87 @@ +from fastecdsa.curve import P256 +from fastecdsa.point import Point +from fastecdsa import util + +from lazarus import Lazarus + +class Bethany(): + pass + +#--- + +e = 31415926535987932384626433832795 +Q = e*P256.G + +class Generalised_Dual_EC_RBG(object): + def __init__(self, Q, seed, curve = P256): + self.curve = curve + self.state = seed + self.Q = Q + self.P = curve.G + self.tmp = None + + assert Q.curve == curve + + def gen(self): + new_point = self.state * self.P + sP = r = new_point.x # remember that the x value of the new point is used for the next point. + rQ = r * self.P + random_int_to_return = int(str(bin((rQ).x))[16:], 2) + self.state = (r*self.Q).x + self.lsb = str(bin((rQ).x)) + self.rQ = rQ + return random_int_to_return + +class breakEccPerm(): + def __init__(self): + pass + + def smash(omegaKey): + integer = int.from_bytes(omegaKey, "big", seed, signed=False ) + breakEccPerm.get_identical_generator(integer, second_output, e, curve) + + def get_identical_generator(output, second_output, e, curve): + # make a new generator and instantiate it with one possible state out of the 65535 + for lsb in range(2**16): + # rudimentary progress bar + if (lsb % 2048) == 0: + print("{}% done checking\r".format(100*lsb/(2**16))) + # bit-shift and then concat to guess most significant bits that were discarded + overall_output = (lsb << (output.bit_length()) | output) + + # zeroth check: is the value greater than p? + if overall_output > curve.p: + global first_rQ # this is only used for debugging and can be removed + # if it is greater, skip this number + # since the most significant bits are iterated through in ascending order. + # if it reaches that point that means we know something went wrong and we can break out + print("""Something went wrong. debugging info: + Output = {}, + lsb = {}, + rQ = {}""".format(output, lsb, first_rQ)) + break + + # calculate a value of y + for sol_to_y in util.mod_sqrt(overall_output**3 - 3*overall_output + curve.b, curve.p): + # there are either 2 or 0 real answers to the square root. We reject those greater than p. + if sol_to_y < curve.p: + possible_y = sol_to_y + else: + possible_y = None + # first check: if there were 0 solutions we can skip this iteration + if possible_y == None or type(possible_y) != int: + continue + + # second check: is point on curve? if not then skip this iteration + try: + possible_point = Point(overall_output, possible_y, curve=curve) + except: + continue + + # if checks were passed, exploit the relation between state to calculate the internal state + possible_state = (e * possible_point).x + # check if the state is correct by generating another output + possible_generator = Generalised_Dual_EC_RBG(Q=Q, seed=possible_state) + if possible_generator.gen() == second_output: + break + return possible_generator diff --git a/break.py b/break.py deleted file mode 100644 index 167d8f2..0000000 --- a/break.py +++ /dev/null @@ -1,180 +0,0 @@ -import os -import sys -import time -import random -import hashlib -import itertools -from base64 import b64encode as b64enc, b64decode as b64dec - -BS = 16 -iv = "0"*BS # set to "" if not known - -class bc: - HEADER = '\033[95m' - OKBLUE = '\033[94m' - OKGREEN = '\033[92m' - WARNING = '\033[93m' - FAIL = '\033[91m' - ENDC = '\033[0m' - BOLD = '\033[1m' - UNDERLINE = '\033[4m' - -def p(t): - sys.stdout.write(t) - - -s = "" -def printScreen(enc,dec,match,status="",less=False): - if less and random.random()maxLen: - break - for ni,n in enumerate(b): - if dec[bi][ni]=="0": - if match!=0: - matchInds = [] - for m in match[ni]: - for i in m[1]: - matchInds.append(i) - if bi in matchInds: - #p(bc.OKBLUE+b64enc(n)[0]+bc.ENDC) - p(b64enc(n)[0]) - else: - #p(b64enc(n)[0]) - p(bc.FAIL+"#"+bc.ENDC) - else: - p(bc.OKGREEN+dec[bi][ni]+bc.ENDC) - print("\n\n"+s+"\n\n") - #time.sleep(0.01) - -def cls(): - os.system('cls' if os.name=='nt' else 'clear') - -def sxor(s1,s2): - return ''.join(chr(ord(a) ^ ord(b)) for a,b in zip(s1,s2)) - -def main(enc): - c = [list(enc[i*BS:][:BS]) for i in range(int(ceil(float(len(enc))/BS)))] - enc = c - dec = [] - for i in enc: - dec.append(["0"]*BS) - printScreen(enc,dec,0,"Cross-Entropy-Mapping") - # nugget 1 nugget 2 - # [ [[char,block],...] , [...] , ... ] - seen = [] - # nugget 1 nugget 2 - # [ [[char,[index1,index2,...],...] , [...] , ... ] - match = [] - - # [[clash,indN,indA,indB],...] - tron = [] - for i in range(BS): - match.append([]) - seen.append([]) - for bi,b in enumerate(enc): #for every block - for ni,n in enumerate(b): #for every nugget - for mi,m in enumerate(match[ni]): - if m[0]==n: # Match already exists, add our new one - m[1].append(bi) # add our Block-Index to the Match - printScreen(enc,dec,match,"",2) - break - else: # No existing Match found; Searching for new one - for si,s in enumerate(seen[ni]): - if s[0]==n: #Found dat Match - # char,[bIndex Seen, bIndex New] - match[ni].append([n,[s[1],bi]]) - printScreen(enc,dec,match,"",2) - break - else: # No Match, Char not in seen - # char, bIndex - seen[ni].append([n,bi]) - - printScreen(enc,dec,match,"Calculating Trons...") - for ni,n in enumerate(match): #for every nugget - for mi,m in enumerate(n): #for every match - for indexA,indexB in itertools.combinations(m[1],2): #for every bIndex-Pair - if indexA==0: - if len(iv)!=0: - tron.append([ sxor(enc[indexB-1][ni],iv), ni, [indexA, indexB]]) - else: - tron.append([ sxor(enc[indexA-1][ni],enc[indexB-1][ni]), ni, [indexA, indexB]]) - - printScreen(enc,dec,match,"Constructing Matrix") - matrix = [] - for i in range(len(enc)*BS): - matrix.append([]) - for j in range(128): - matrix[i] = [1]*128 - - printScreen(enc,dec,match,"Planting Seeds...") - for ti,t in enumerate(tron): - bin = '{0:07b}'.format(ord(t[0])) - for b in [0,1]: - if bin[:2]=="00": - # is 00****** - # but to be valid, it has to be 001***** -> min 32 - for i in range(32): - matrix[t[2][b]*8+t[1]][i] = 0 - elif bin[:2]=="10": - # is 10****** - # first bit is not allowes to flip - for i in range(64,128): - matrix[t[2][b]*8+t[1]][i] = 0 - elif bin[:2]=="11": - # is 11****** - # first 2 bits are not allowes to flip - for i in range(96,128): - matrix[t[2][b]*8+t[1]][i] = 0 - elif bin[:2]=="01": - # is 01****** - # second bit is only allowed to flip, - # if first bit flips - for i in range(32,64): - matrix[t[2][b]*8+t[1]][i] = 0 - - legals = [] - legals.append([45,46,47]) - legals.append(range(65,90)) - legals.append([95]) - legals.append([97,122]) - - tronHistory = [] - - printScreen(enc,dec,match,"Growing Seeds...") - while True: - p(".") - hash = hashlib.sha256(str(tron)).hexdigest() - if hash in tronHistory: - break - tronHistory.append(hash) - for ti,t in enumerate(tron): - for direction in [0,1]: - for possibilityA,avaibleA in enumerate(matrix[t[2][direction]*8+t[1]]): - if avaibleA: - for possibilityB,avaibleB in enumerate(matrix[t[2][direction]*8+t[1]]): - if avaibleB: - if (possibilityA ^ possibilityB) not in legals: - matrix[t[2][direction]*8+t[1]][possibilityA] = 0 - matrix[t[2][direction]*8+t[1]][possibilityB] = 0 - for m in matrix: - l = 0 - for i in m: - if i: - l+=1 - if l==1: - print("Yay!") - -if __name__=="__main__": - from lazarus import * - lazarus = Lazarus("This is a safe Password") - knownDec = "This is a very very long text message, that I use to text my text. If you read this text, dont think it is your text just because you read it, it is still my text! So: Fuck of and get you own text, if you want one, asshole..."*200 - enc = lazarus.enc(knownDec) - main(enc) diff --git a/lazarus.py b/lazarus.py index 4755c18..e0f8bc3 100644 --- a/lazarus.py +++ b/lazarus.py @@ -1,48 +1,110 @@ -from math import ceil -from urllib2 import quote, unquote -from base64 import b64encode as b64enc +import hashlib +import math + +from fastecdsa.curve import P256 +from fastecdsa.point import Point +from fastecdsa import util + +Q = 31415926535987932384626433832795*P256.G + +class EccRNG(): + def __init__(self, Q, seed, curve = P256): + self.curve = curve + self.state = int.from_bytes(seed, "big", seed, signed=False ) + self.Q = Q + self.P = curve.G + self.tmp = None + assert Q.curve == curve + + def gen(self): + new_point = self.state * self.P + r = new_point.x + rQ = r * self.P + random_int_to_return = int(str(bin((rQ).x))[16:], 2) + self.state = (r*self.Q).x + self.lsb = str(bin((rQ).x)) + self.rQ = rQ + return random_int_to_return.to_bytes(math.ceil(random_int_to_return.bit_length()/8), byteorder='big') + +class LazarusKeyScheduler(): + def __init__(self, password: bytes, nonce: bytes): + self.ecc = EccRNG() + self.hashState = hashlib.sha3_256(password + nonce + password).digest() + self.eccState = self.ecc.gen() + for i in range(64): + self._stateStep() + + def genToken(self): + self._stateStep() + return self.state + self.eccState + + def getKey(self, length: int): + return hashlib.shake_256(self.genToken()).digest(length) + + def _stateStep(self): + self.eccState = self.ecc.gen() + self.hashState = hashlib.sha3_256(self.hashState + self.eccState).digest() + +class OmegaChain(): + def __init__(self, key: bytes, primer: bytes): + self.blockSize = 16 + self.prevBlock = primer + self.key = key + + def encrypt(self, data: bytes): + blocks = self._dataToBlocks(data) + enc = bytes() + for block in blocks: + enc += self.encBlock(block) + + def _encBlock(self, plainBlock: bytes): + chainedBlock = self._xor(self.prevBlock, plainBlock) + encBlock = self._xor(chainedBlock, self.key) + self.prevBlock = encBlock + return encBlock + + def _xor(self, a: bytes, b: bytes): + if len(a)!=self.blockSize or len(b)!=self.blockSize: + raise Exception("Cannot xor") #TODO + return bytes([a[i]^b[i] for i in range(len(a))]) + + def _dataToBlocks(self, data: bytes): + padded = self._padData(data, blockSize = self.blockSize) + return [data[b*self.blockSize:self.blockSize] for b in range(int(len(padded)/self.blockSize))] + + def _padData(self, data: bytes, blockSize: int = None): + if not blockSize: + blockSize = self.blockSize + bytesMissing = (blockSize-len(data)%blockSize) + if bytesMissing == blockSize: + return data + else: + return data + bytes(bytesMissing) class Lazarus(): - def __init__(self, key): - self.key = key - self.BS = 16 - self.iv = "0"*self.BS + def encrypt(password: bytes, plaintext: bytes, nonce: bytes = None): + if not nonce: + #TODO: Random iv + nonce = b'bla' + scheduler = LazarusKeyScheduler(password, nonce) + omegaKey = scheduler.genToken() + primer = scheduler.getKey(16) + aesKey = scheduler.getKey(16) + aesIV = scheduler.getKey(16) + hmacInnerKey = scheduler.getKey(16) + hmacOuterKey = scheduler.getKey(16) - def enc(self, plaintext): - t = quote(plaintext) - prevBlock = self.iv - c = "" - for i in range(int(ceil(float(len(t))/self.BS))): - block = t[i*self.BS:][:self.BS] - prevBlock=self._sxor(self._rc4(block),prevBlock) - c+=prevBlock - return c + alpha = Lazarus._encryptAES(plaintext, aesKey, aesIV) + hmac = Lazarus._genHMAC(plaintext, hmacInnerKey, hmacOuterKey) + psi = alpha + hmac + omega = OmegaChain(omegaKey, primer) + return omega.encrypt(psi) - def dec(self, ciphertext): - c = ciphertext - prevBlock = self.iv - t = "" - for i in range(int(ceil(float(len(c))/self.BS))): - block = c[i*self.BS:][:self.BS] - t+=self._rc4(self._sxor(block,prevBlock)) - prevBlock = block - return unquote(t) + def omegaChain(prev: bytes, scheduler: LazarusKeyScheduler): + pass - def _sxor(self, s1, s2): - return ''.join(chr(ord(a) ^ ord(b)) for a,b in zip(s1,s2)) + def eccPerm(self, key: bytes): + pass - def _rc4(self, data): - box = list(range(256)) - x = 0 - for i in range(256): - x = (x + box[i] + ord(self.key[i % len(self.key)])) % 256 - box[i], box[x] = box[x], box[i] - x = 0 - y = 0 - out = [] - for char in data: - x = (x + 1) % 256 - y = (y + box[x]) % 256 - box[x], box[y] = box[y], box[x] - out.append(chr(ord(char) ^ box[(box[x] + box[y]) % 256])) - return ''.join(out) + def primePerm(self, key: bytes): + pass diff --git a/lazarus.pyc b/lazarus.pyc deleted file mode 100644 index f5c678851839ed8e42ca17328ed7482bcdf33672..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2768 zcmcImQEwYX5T5nf=Oi>Gv}w|`MF~iNU#OEPEiX|;(@01NEOe2GFhth*?wXu?_Stvq z%Bh^E@C%Umm%Q-<;QMCngg(F%w!L$+b9b||^UZu~@6XkhKY}MeM>6|(xPFaMeh(4j zXCxEp8)+LcoL3~PNZ*sTC;h6ltIq04R+GLj?K^_4EBgB!Vrpb6($Q2~-KnX<#@}ehaO6k@u5koX7d3 zSq{QsbC67Il;z|2%P32efo<;XHd}LB^M@kuC6O(gnM=(4`gC|{ne|R59i+C?;YuZi zm}Pu*zf3nxy5HZRSl#lqk*oPOuaG=Ut1=l1wt!6mJRoL$nN|c(;>U#4<$;?(9-qCE zs~Yc5A@%0^w!7|J;XPQER4&WZR|lS4R|HEPD%goE=$Go21>0IM^<&hpTzIZFlsx2aEe%1K^m@pX#mph0`U3bPc$EQAl_RWY>A zRwQqavOIdDwn$~FuDY}?4ms8iiv9y!O4gN_I{?i$`{to}Z0`OGd??o$aKdcf0%zXC z?mgiA{{qez2b?bo9MDlTX9xmH1rCrCGGK{CM=#|RxdV1E&)^HV4+kHS3+_;?Qea4M zm*PVTMdTxD+;qUs`3FkGKT3xeNkN!`2Yh6m;y%R&#U{jJQHhg?3(rvTZ&2AbD<&dr z9Ap%2svRhRp{L{t3PJ^uQ_wjTId%;*qYuqd#Oj_qD4~~o5J>mg7xD`_MDay4I5&8o zinifPOnx*YfKEc9o0g**dW$X!ZHByv9W^nrPj|JPLzUfyC9Py{9iAs(v0?FI2a}Sk z`*O>Ky&R3lINzm1jn6eDA1n8iH_QEn#iy0FJr7GIz6!r?F( z#KB`4cOdk?f~x=?lW}N6EskzJ(Ndjgr>lDDs(Ng7mFOZY7FQ-@rB5+RZb8gFknw%9 zYd*o1-&K(EJ@c`7W|XjINADo)C!LNZadkTVJRWD526~P?ge`bPp;Slrx52CSKmQvD zm`xH>$@M{8wdECjy_Q>6&p|%Y5AB6JNy*0JBFob5zB_i=k&0P2ER*L40ejZX^)H&P Yu-Hv#UJqR+U$D~jFU^|SFl&{+0eT!19smFU diff --git a/note.py b/note.py deleted file mode 100644 index ec16674..0000000 --- a/note.py +++ /dev/null @@ -1,48 +0,0 @@ - -class AESModeOfOperationCBC(AESBlockModeOfOperation): - '''AES Cipher-Block Chaining Mode of Operation. - o The Initialization Vector (IV) - o Block-cipher, so data must be padded to 16 byte boundaries - o An incorrect initialization vector will only cause the first - block to be corrupt; all other blocks will be intact - o A corrupt bit in the cipher text will cause a block to be - corrupted, and the next block to be inverted, but all other - blocks will be intact. - Security Notes: - o This method (and CTR) ARE recommended. - Also see: - o https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher-block_chaining_.28CBC.29 - o See NIST SP800-38A (http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf); section 6.2''' - - - name = "Cipher-Block Chaining (CBC)" - - def __init__(self, key, iv = None): - if iv is None: - self._last_cipherblock = [ 0 ] * 16 - elif len(iv) != 16: - raise ValueError('initialization vector must be 16 bytes') - else: - self._last_cipherblock = _string_to_bytes(iv) - - AESBlockModeOfOperation.__init__(self, key) - - def encrypt(self, plaintext): - if len(plaintext) != 16: - raise ValueError('plaintext block must be 16 bytes') - - plaintext = _string_to_bytes(plaintext) - precipherblock = [ (p ^ l) for (p, l) in zip(plaintext, self._last_cipherblock) ] - self._last_cipherblock = self._aes.encrypt(precipherblock) - - return _bytes_to_string(self._last_cipherblock) - - def decrypt(self, ciphertext): - if len(ciphertext) != 16: - raise ValueError('ciphertext block must be 16 bytes') - - cipherblock = _string_to_bytes(ciphertext) - plaintext = [ (p ^ l) for (p, l) in zip(self._aes.decrypt(cipherblock), self._last_cipherblock) ] - self._last_cipherblock = cipherblock - - return _bytes_to_string(plaintext)