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