def encode(self, k, M, L=''): """ Encode a message using OAEP. This method encodes a byte string 'M' using Optimal Asymmetric Encryption Padding. The argument 'k' must be the size of the private key modulus in bytes. If specified, 'L' is a label for the encoding. """ # Calculate label hash, unless it is too long. if L: limit = getattr(self.hash, 'input_limit', None) if limit and len(L) > limit: raise CryptError('encrypt label too long') lHash = self.hash(L).digest() # Check length of message against size of key modulus mLen = len(M) hLen = len(lHash) if mLen > k - 2 * hLen - 2: raise CryptError('encrypt message too long') # Perform the encoding. PS = '\x00' * (k - mLen - 2 * hLen - 2) DB = lHash + PS + '\x01' + M assert len(DB) == k - hLen - 1, 'DB length is incorrect' seed = self.randbytes(hLen) dbMask = self.mgf(seed, k - hLen - 1) maskedDB = strxor(DB, dbMask) seedMask = self.mgf(maskedDB, hLen) maskedSeed = strxor(seed, seedMask) return '\x00' + maskedSeed + maskedDB
def decode(self, k, EM, L=b''): """ Decode a message using OAEP. This method decodes a byte string 'EM' using Optimal Asymmetric Encryption Padding. The argument 'k' must be the size of the private key modulus in bytes. If specified, 'L' is the label used for the encoding. """ # Generate label hash, for sanity checking. lHash = self.hash(L).digest() assert isinstance(lHash, bytes) hLen = len(lHash) # Split the encoded message. Y = EM[0] maskedSeed = EM[1:(hLen + 1)] maskedDB = EM[(hLen + 1):] # Perform the decoding. seedMask = self.mgf(maskedDB, hLen) seed = strxor(maskedSeed, seedMask) dbMask = self.mgf(seed, k - hLen - 1) DB = strxor(maskedDB, dbMask) # Split the DB string. lHash1 = DB[:hLen] x01pos = hLen while x01pos < len(DB) and DB[x01pos] not in (b'\x01', 1): x01pos += 1 M = DB[(x01pos + 1):] # All sanity-checking done at end, to avoid timing attacks. valid = True if x01pos == len(DB): # No \x01 byte valid = False if lHash1 != lHash: # Mismatched label hash valid = False if Y not in (b'\x00', 0): # Invalid leading byte valid = False if not valid: raise CryptError('decrypt de-padding failed validation') return M