off to a new start...
This commit is contained in:
parent
3c169e270a
commit
d19d35c4d4
BIN
__pycache__/lazarus.cpython-38.pyc
Normal file
BIN
__pycache__/lazarus.cpython-38.pyc
Normal file
Binary file not shown.
Binary file not shown.
87
bethany.py
Normal file
87
bethany.py
Normal 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
180
break.py
@ -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)
|
146
lazarus.py
146
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
|
||||
|
BIN
lazarus.pyc
BIN
lazarus.pyc
Binary file not shown.
48
note.py
48
note.py
@ -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)
|
Loading…
Reference in New Issue
Block a user