off to a new start...

This commit is contained in:
Dominik Moritz Roth 2020-06-25 11:44:13 +02:00
parent 3c169e270a
commit d19d35c4d4
7 changed files with 191 additions and 270 deletions

Binary file not shown.

Binary file not shown.

87
bethany.py Normal file
View File

@ -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

180
break.py
View File

@ -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()<float("0."+"9"*less):
return
global s
maxLen = 10
if status != "":
s = status
cls()
print(knownDec[:maxLen*BS])
for bi,b in enumerate(enc):
if bi>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)

View File

@ -1,48 +1,110 @@
from math import ceil import hashlib
from urllib2 import quote, unquote import math
from base64 import b64encode as b64enc
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(): class Lazarus():
def __init__(self, key): def encrypt(password: bytes, plaintext: bytes, nonce: bytes = None):
self.key = key if not nonce:
self.BS = 16 #TODO: Random iv
self.iv = "0"*self.BS 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): alpha = Lazarus._encryptAES(plaintext, aesKey, aesIV)
t = quote(plaintext) hmac = Lazarus._genHMAC(plaintext, hmacInnerKey, hmacOuterKey)
prevBlock = self.iv psi = alpha + hmac
c = "" omega = OmegaChain(omegaKey, primer)
for i in range(int(ceil(float(len(t))/self.BS))): return omega.encrypt(psi)
block = t[i*self.BS:][:self.BS]
prevBlock=self._sxor(self._rc4(block),prevBlock)
c+=prevBlock
return c
def dec(self, ciphertext): def omegaChain(prev: bytes, scheduler: LazarusKeyScheduler):
c = ciphertext pass
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 _sxor(self, s1, s2): def eccPerm(self, key: bytes):
return ''.join(chr(ord(a) ^ ord(b)) for a,b in zip(s1,s2)) pass
def _rc4(self, data): def primePerm(self, key: bytes):
box = list(range(256)) pass
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)

Binary file not shown.

48
note.py
View File

@ -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)