def decode(self, encMessage, label=""): hLen = self.hashFnOutputBytes # Make sure the encoded string is at least L bytes long if len(encMessage) < (2 * hLen + 2): assert False, "encoded string not long enough." if py3: lHash = self.hashFn(Bytes(label, 'utf-8')) else: lHash = self.hashFn(Bytes(label)) # Parse the encoded string as (0x00 || maskedSeed || maskedDB) #Y = encMessage[0] maskedSeed = Bytes(encMessage[1:(1 + hLen)]) maskedDB = Bytes(encMessage[(1 + hLen):]) # Set seedMask = MGF1(maskedDB, hashFnOutputSize) seedMask = MGF1(maskedDB, len(maskedSeed), self.hashFn, hLen) seed = maskedSeed ^ seedMask # Set dbMask = MGF(seed, k - hLen - 1) and # DB = maskedDB \xor dbMask. dbMask = MGF1(seed, len(maskedDB), self.hashFn, hLen) DB = dbMask ^ maskedDB if (debug): print("decoding:") print("MaskedSeed => ", maskedSeed) print("maskedDB => ", maskedDB) print("r seed =>", seed) print("r DB =>", DB) # Parse DB as: # DB = lHash' || PS || 0x01 || M. # Check that lHash' == lHash, Y == 0x00 and there is an 0x01 after PS lHashPrime = DB[0:hLen] M = DB[DB.find(b'\x01') + 1:] return M
def myrandom(self, length, printable=False): ''' This method does **NOT** provide cryptographically secure random numbers. This should **NOT** be used for production code ''' if (printable): #Nice printable characters for testing purposes return Bytes(random.randrange(0x20, 0x7E) for i in range(length)) else: return Bytes(random.randrange(0, 256) for i in range(length))
def __call__(self, message): h = self.hashObj.copy() if type(message) == str: h.update(bytes(message)) elif type(message) in [bytes, Bytes]: h.update(bytes(message)) # bytes or custom Bytes return Bytes(h.digest())
def IP2OS(self, number, xLen=None): ''' :Parameters: - ``number``: is a normal integer, not modular - ``xLen``: is the intended length of the resulting octet string Converts an integer into a byte string''' ba = bytearray() x = 0 if type(number) == integer: x = int(number) elif type(number) == int: x = number elif not py3 and type(number) == long: x = number if xLen == None: xLen = int(math.ceil(math.log(x, 2) / 8.0)) for i in range(xLen): ba.append(x % 256) x = x >> 8 ba.reverse() return Bytes(ba)
def encode(self, message, emLen, label="", seed=None): ''':Return: a Bytes object''' # Skipped: label input length checking. (L must be less than 2^61 octets for SHA1) # First, make sure the message isn't too long. emLen hLen = self.hashFnOutputBytes if (len(message) > (emLen - (2 * hLen) - 2)): assert False, "message too long" if py3: lHash = self.hashFn(Bytes(label, 'utf8')) else: lHash = self.hashFn(Bytes(label)) # Let PS be a string of length (emLen - mLen - 2hLen - 2) containing only zero octets. # Compute DB = lHash || PS || 0x01 || M. PS = Bytes.fill(b'\x00', emLen - len(message) - (2 * hLen) - 2) DB = lHash + PS + b'\x01' + bytes(message) # Generate a random octet string seed of length hLen and compute # maskedDB = MGF1(seed, emLen - self.hashFnOutputBytes - 1) if (seed is None): rand = SecureRandomFactory.getInstance() seed = rand.getRandomBytes(hLen) dbMask = MGF1(seed, len(DB), self.hashFn, hLen) maskedDB = DB ^ dbMask # Let seedMask = MGF(maskedDB, self.hashFnOutputBytes) and # maskedSeed = seedMask XOR seed seedMask = MGF1(maskedDB, len(seed), self.hashFn, hLen) maskedSeed = seedMask ^ seed if (debug): print("Encoding") print("label =>", label) print("lhash =>", lHash) print("seed =>", seed) print("db =>", DB) print("db len =>", len(DB)) print("db mask =>", dbMask) print("maskedDB =>", maskedDB) print("seedMask =>", seedMask) print("maskedSed=>", maskedSeed) return Bytes(b'\x00') + maskedSeed + maskedDB
def strToId(self, pk, strID): h = hashObj.copy() h.update(bytes(strID, 'utf-8')) hash = Bytes(h.digest()) val = Conversion.OS2IP(hash) bstr = bin(val)[2:] v = [] for i in range(pk['x']): binsubstr = bstr[pk['l'] * i:pk['l'] * (i + 1)] intval = int(binsubstr, 2) intelement = group.init(ZR, intval) v.append(intelement) return v
def stringtoidentity(self, pk, strID): '''Hash the identity string and break it up in to l bit pieces''' hash = self.sha1(Bytes(strID, 'utf-8')) val = Conversion.OS2IP(hash) #Convert to integer format bstr = bin(val)[2:] #cut out the 0b header v=[] for i in range(pk['n']): #n must be greater than or equal to 1 binsubstr = bstr[pk['l']*i : pk['l']*(i+1)] intval = int(binsubstr, 2) intelement = group.init(ZR, intval) v.append(intelement) return v
def HW_hash(self, key, c, input, keyLen): # Return c XOR PRF(k, input), where the output of PRF is keyLength bits if type(input) != str: input_temp = input input_s = '' while input_temp > 0: input_s = chr(input_temp & 0xff) + input_s input_temp = input_temp >> 8 input_b = Bytes(input_s, 'utf8') else: assert False, "Invalid input: need an integer." result = integer(c) ^ self.Prf.eval(key, input_b, keyLen) #print("HW_hash =>", result) return result
def encode(self, message, n, s0): #n = m + s0 + s1 m = int(n/4) #usually 256 bits if(len(message) > (m/8)): assert False, "message too long" if(len(message) != m): message_ext = bytes(message) + Bytes.fill(b'\x80', 1) if(len(message_ext) != m): message_ext = bytes(message_ext) + Bytes.fill(b'\x00', ((m/8)-2)-len(message)) message_ext = bytes(message_ext) + Bytes.fill(b'\x80', 1) s1 = n - m - s0 t = Bytes.fill(b'\x00', s0/8) rand = SecureRandomFactory.getInstance() r = rand.getRandomBytes(int(s1/8)) v = Bytes(bytes(message_ext) + t) x = v ^ self.hashFn(r) y = x + r if(debug): print("Encoding") print("m =>", m) print("s0 =>", s0) print("s1 =>", s1) print("t =>", t, len(t)) print("r =>", r, len(r)) print("v =>", v, len(v)) print("x =>", x) print("y =>", y, len(y)) return y
def verify(self, mpk, ID, M, sig): h = hashObj.copy() h.update(bytes(ID, 'utf-8')) hash = Bytes(h.digest()) val = Conversion.OS2IP(hash) bstr = bin(val)[2:] v = [] for i in range(mpk['x']): binsubstr = bstr[mpk['l'] * i:mpk['l'] * (i + 1)] intval = int(binsubstr, 2) intelement = group.init(ZR, intval) v.append(intelement) k = v h = hashObj.copy() h.update(bytes(M, 'utf-8')) hash = Bytes(h.digest()) val = Conversion.OS2IP(hash) bstr = bin(val)[2:] v = [] for i in range(mpk['x']): binsubstr = bstr[mpk['l'] * i:mpk['l'] * (i + 1)] intval = int(binsubstr, 2) intelement = group.init(ZR, intval) v.append(intelement) m = v S1 = sig['S1'] S2 = sig['S2'] S3 = sig['S3'] A = mpk['A'] g2 = mpk['g2'] comp1 = dotprod(group.init(G2), -1, mpk['x'], lam_func, mpk['ub'], k) comp2 = dotprod(group.init(G2), -1, mpk['x'], lam_func, mpk['ub'], m) if (pair(S1, g2) * pair(S2, mpk['u1b'] * comp1) * pair(S3, mpk['u2b'] * comp2)) == A: return True return False
def encode(self, message, emLen, label="", seed=None): ''':Return: a Bytes object''' # Skipped: label input length checking. (L must be less than 2^61 octets for SHA1) # First, make sure the message isn't too long. emLen hLen = self.hashFnOutputBytes if (len(message) > (emLen - (2 * hLen) - 2)): assert False, "message too long" if py3: lHash = self.hashFn(Bytes(label, 'utf8')) else: lHash = self.hashFn(Bytes(label)) # Let PS be a string of length (emLen - mLen - 2hLen - 2) containing only zero octets. # Compute DB = lHash || PS || 0x01 || M. PS = Bytes.fill(b'\x00', emLen - len(message) - (2 * hLen) - 2) DB = lHash + PS + b'\x01' + bytes(message) # Generate a random octet string seed of length hLen and compute # maskedDB = MGF1(seed, emLen - self.hashFnOutputBytes - 1) if (seed is None): rand = SecureRandomFactory.getInstance() seed = rand.getRandomBytes(hLen) dbMask = MGF1(seed, len(DB), self.hashFn, hLen) maskedDB = DB ^ dbMask # Let seedMask = MGF(maskedDB, self.hashFnOutputBytes) and # maskedSeed = seedMask XOR seed seedMask = MGF1(maskedDB, len(seed), self.hashFn, hLen) maskedSeed = seedMask ^ seed if(debug): print("Encoding") print("label =>", label) print("lhash =>", lHash) print("seed =>", seed) print("db =>", DB) print("db len =>", len(DB)) print("db mask =>", dbMask) print("maskedDB =>", maskedDB) print("seedMask =>", seedMask) print("maskedSed=>", maskedSeed) return Bytes(b'\x00') + maskedSeed + maskedDB
def MGF1(seed, maskBytes, hashFn, hLen): ''' MGF1 Mask Generation Function Implemented according to PKCS #1 specification, see appendix B.2.1: :Parameters: - ``hLen``: is the output length of the hash function - ``maskBytes``: the number of mask bytes to return ''' debug = False # Skipped output size checking. Must be less than 2^32 * hLen ran = range(int(math.ceil(maskBytes / float(hLen)))) if debug: print("calc =>", math.ceil(maskBytes / float(hLen))) print("Range =>", ran) test = [hashFn(struct.pack(">%dsI" % (len(seed)), seed, i)) for i in ran] if debug: print("test =>", test) result = b''.join(test) return Bytes(result[0:maskBytes])
def keygen(self, mpk, msk, ID): h = hashObj.copy() h.update(bytes(ID, 'utf-8')) hash = Bytes(h.digest()) val = Conversion.OS2IP(hash) bstr = bin(val)[2:] v = [] for i in range(mpk['x']): binsubstr = bstr[mpk['l'] * i:mpk['l'] * (i + 1)] intval = int(binsubstr, 2) intelement = group.init(ZR, intval) v.append(intelement) k = v r = group.random(ZR) k1 = msk * ( (mpk['u1t'] * dotprod(group.init(G1), -1, mpk['x'], lam_func, mpk['u'], k))**r) k2 = mpk['g1']**-r sk = (k1, k2) return sk
def sign(self, mpk, sk, M): h = hashObj.copy() h.update(bytes(M, 'utf-8')) hash = Bytes(h.digest()) val = Conversion.OS2IP(hash) bstr = bin(val)[2:] v = [] for i in range(mpk['x']): binsubstr = bstr[mpk['l'] * i:mpk['l'] * (i + 1)] intval = int(binsubstr, 2) intelement = group.init(ZR, intval) v.append(intelement) m = v (k1, k2) = sk s = group.random(ZR) S1 = k1 * ( (mpk['u2t'] * dotprod(group.init(G1), -1, mpk['x'], lam_func, mpk['u'], m))**s) S2 = k2 S3 = mpk['g1']**-s sig = {'S1': S1, 'S2': S2, 'S3': S3} return sig
def decrypt(self, pk, sk, c): p = sk['p'] q = sk['q'] yp = sk['yp'] yq = sk['yq'] mp = (c ** ((p+1)/4)) % p mq = (c ** ((q+1)/4)) % q if(not(((c % p) == (mp ** 2)) and ((c % q) == (mq ** 2)))): assert False, "invalid ciphertext" r1 = ((int(yp)*int(p)*int(mq)) + ((int(yq)*int(q)*int(mp)))) % int(sk['N']) r2 = int(sk['N']) - int(r1) s1 = (int(yp)*int(p)*int(mq) - int(yq)*int(q)*int(mp)) % int(sk['N']) s2 = int(sk['N']) - int(s1) m1 = r1 % int(sk['N']) m2 = r2 % int(sk['N']) m3 = s1 % int(sk['N']) m4 = s2 % int(sk['N']) if(self.paddingscheme.name == "SAEPEncryptionPadding"): if(m1 < int(sk['N']/2)): os1 = Conversion.IP2OS(int(m1)) if(m2 < int(sk['N']/2)): os2 = Conversion.IP2OS(int(m2)) else: if(m3 < int(sk['N']/2)): os2 = Conversion.IP2OS(int(m3)) else: os2 = Conversion.IP2OS(int(m4)) else: if(m2 < int(sk['N']/2)): os1 = Conversion.IP2OS(int(m2)) if(m3 < int(sk['N']/2)): os2 = Conversion.IP2OS(int(m3)) else: os2 = Conversion.IP2OS(int(m4)) else: os1 = Conversion.IP2OS(int(m3)) os2 = Conversion.IP2OS(int(m4)) if debug: print("OS1 =>", os1) print("OS2 =>", os2) (m1, t1) = self.paddingscheme.decode(os1, pk['n'], pk['s0']) (m2, t2) = self.paddingscheme.decode(os2, pk['n'], pk['s0']) if((t1 == Bytes.fill(b'\x00', pk['s0']/8)) and (t2 == Bytes.fill(b'\x00', pk['s0']/8))): assert False, "invalid ciphertext" if(t1 == Bytes.fill(b'\x00', pk['s0']/8)): return m1 else: if(t2 == Bytes.fill(b'\x00', pk['s0']/8)): return m2 else: assert False, "invalid ciphertext" else: octetlen = int(ceil(int(pk['N']).bit_length() / 8.0)) os1 = Conversion.IP2OS(int(m1), octetlen) os2 = Conversion.IP2OS(int(m2), octetlen) os3 = Conversion.IP2OS(int(m3), octetlen) os4 = Conversion.IP2OS(int(m4), octetlen) if debug: print("OS1 =>", os1) print("OS2 =>", os2) print("OS3 =>", os3) print("OS4 =>", os4) for i in [os1, os2, os3, os4]: (isMessage, message) = self.redundancyscheme.decode(self.paddingscheme.decode(i)) if(isMessage): return message
def sha1(message): h = hashObj.copy() h.update(bytes(message, 'utf-8')) return Bytes(h.digest())
def verifySigsRecursive(group, deltaz, verifyFuncArgs, argSigIndexMap, verifyArgsDict, dotA, dotB, dotD, sumE, mpk_1, mpk_6, mpk_7, A, startIndex, endIndex): l = 5 sigNumKey = 'Signature_Number' hashObj = hashlib.new('sha1') lam_func = lambda i, a, b: a[i]**b[i] for arg in verifyFuncArgs: argSigIndexMap[arg] = 0 dotA_runningProduct = group.init(G1, 1) dotB_runningProduct = group.init(G1, 1) dotF_runningProduct = group.init(GT, 1) dotD_runningProduct = group.init(G1, 1) sumE_runningProduct = group.init(ZR, 0) dotF_runningProduct = group.init(GT, 1) for y in range(0, l): dotC_runningProduct = group.init(G1, 1) for z in range(startIndex, endIndex): for arg in verifyFuncArgs: if (sigNumKey in verifyArgsDict[z][arg]): argSigIndexMap[arg] = int( verifyArgsDict[z][arg][sigNumKey]) else: argSigIndexMap[arg] = z h = hashObj.copy() h.update( bytes(verifyArgsDict[argSigIndexMap['ID']]['ID'][bodyKey], 'utf-8')) hash = Bytes(h.digest()) val = Conversion.OS2IP(hash) bstr = bin(val)[2:] v = [] for i in range(verifyArgsDict[argSigIndexMap['mpk']]['mpk'] [bodyKey]['x']): binsubstr = bstr[verifyArgsDict[ argSigIndexMap['mpk']]['mpk'][bodyKey]['l'] * i:verifyArgsDict[argSigIndexMap['mpk']]['mpk'] [bodyKey]['l'] * (i + 1)] intval = int(binsubstr, 2) intelement = group.init(ZR, intval) v.append(intelement) k = v h = hashObj.copy() h.update( bytes(verifyArgsDict[argSigIndexMap['M']]['M'][bodyKey], 'utf-8')) hash = Bytes(h.digest()) val = Conversion.OS2IP(hash) bstr = bin(val)[2:] v = [] for i in range(verifyArgsDict[argSigIndexMap['mpk']]['mpk'] [bodyKey]['x']): binsubstr = bstr[verifyArgsDict[ argSigIndexMap['mpk']]['mpk'][bodyKey]['l'] * i:verifyArgsDict[argSigIndexMap['mpk']]['mpk'] [bodyKey]['l'] * (i + 1)] intval = int(binsubstr, 2) intelement = group.init(ZR, intval) v.append(intelement) m = v S2 = verifyArgsDict[argSigIndexMap['sig']]['sig'][bodyKey]['S2'] S3 = verifyArgsDict[argSigIndexMap['sig']]['sig'][bodyKey]['S3'] dotC_runningProduct = dotC_runningProduct * ( S2**(deltaz[z] * k[y]) * S3**(deltaz[z] * m[y])) dotF_runningProduct = dotF_runningProduct * pair( dotC_runningProduct, verifyArgsDict[argSigIndexMap['mpk']]['mpk'][bodyKey]['ub'][y]) for index in range(startIndex, endIndex): dotA_runningProduct = dotA_runningProduct * dotA[index] dotB_runningProduct = dotB_runningProduct * dotB[index] dotD_runningProduct = dotD_runningProduct * dotD[index] sumE_runningProduct = sumE_runningProduct + sumE[index] if (pair(dotA_runningProduct, mpk_1) * ((pair(dotB_runningProduct, mpk_6) * dotF_runningProduct) * pair(dotD_runningProduct, mpk_7))) == A**sumE_runningProduct: return else: midWay = int((endIndex - startIndex) / 2) if (midWay == 0): print("sig " + str(startIndex) + " failed\n") return midIndex = startIndex + midWay verifySigsRecursive(group, deltaz, verifyFuncArgs, argSigIndexMap, verifyArgsDict, dotA, dotB, dotD, sumE, mpk_1, mpk_6, mpk_7, A, startIndex, midIndex) verifySigsRecursive(group, deltaz, verifyFuncArgs, argSigIndexMap, verifyArgsDict, dotA, dotB, dotD, sumE, mpk_1, mpk_6, mpk_7, A, midIndex, endIndex)
group = groupParamArg lam_func = lambda i, a, b: a[i]**b[i] for sigIndex in range(0, numSigs): for arg in verifyFuncArgs: if (sigNumKey in verifyArgsDict[sigIndex][arg]): argSigIndexMap[arg] = int( verifyArgsDict[sigIndex][arg][sigNumKey]) else: argSigIndexMap[arg] = sigIndex h = hashObj.copy() h.update( bytes(verifyArgsDict[argSigIndexMap['ID']]['ID'][bodyKey], 'utf-8')) hash = Bytes(h.digest()) val = Conversion.OS2IP(hash) bstr = bin(val)[2:] v = [] for i in range( verifyArgsDict[argSigIndexMap['mpk']]['mpk'][bodyKey]['x']): binsubstr = bstr[ verifyArgsDict[argSigIndexMap['mpk']]['mpk'][bodyKey]['l'] * i:verifyArgsDict[argSigIndexMap['mpk']]['mpk'][bodyKey]['l'] * (i + 1)] intval = int(binsubstr, 2) intelement = group.init(ZR, intval) v.append(intelement) k = v h = hashObj.copy() h.update(
def encode(self, message): return Bytes(b'\x00') + maskedSeed + maskedDB
def encode(self, M, emBits=None, salt=None): '''Encodes a message with PSS padding emLen will be set to the minimum allowed length if not explicitly set ''' # assert len(M) < (2^61 -1), Message too long #Let H' = Hash (M'), an octet string of length hLen. #Max length of output message if emBits is None: emBits = 8*self.hLen + 8 * self.sLen + 9 #Round to the next byte emBits = int(math.ceil(emBits / 8.0)) * 8 assert emBits >= 8*self.hLen + 8 * self.sLen + 9, "Not enough emBits" #Make sure the the message is long enough to be valid emLen = int(math.ceil(emBits / 8.0)) assert emLen >= self.hLen + self.sLen + 2, "emLen too small" if salt is None: if self.sLen > 0: salt = SecureRandomFactory.getInstance().getRandomBytes(self.sLen) else: salt = b'' assert len(salt) == self.sLen, "Salt wrong size" #Let M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt; eightzerobytes = Bytes.fill(b'\x00', 8) mHash = self.hashFn(M) Mprime = eightzerobytes + mHash + salt #Let H = Hash (M'), an octet string of length hLen. H = self.hashFn(Mprime) #Generate an octet string PS consisting of emLen - sLen - hLen - 2 zero octets. #The length of PS may be 0. pslen = emLen - self.sLen - self.hLen - 2 ps = Bytes.fill(b'\x00', pslen) #Let DB = PS || 0x01 || salt; DB is an octet string of length emLen - hLen - 1. DB = ps + Bytes(b'\x01') + salt #Let dbMask = MGF (H, emLen - hLen - 1). masklen = emLen - self.hLen - 1 dbMask = MGF1(H, masklen, self.hashFn, self.hLen) #Let maskedDB = DB ^ dbMask. maskedDB = DB ^ dbMask #Set the leftmost 8emLen - emBits bits of the leftmost octet in maskedDB to zero numzeros = 8 * emLen - emBits bitmask = int('0'*numzeros + '1'*(8-numzeros), 2) ba = bytearray(maskedDB) ba[0] &= bitmask maskedDB = Bytes(ba) EM = maskedDB + H + Bytes(b'\xbc') if debug: print("PSS Encoding:") print("M =>", M) print("mHash =>", mHash) print("salt =>", salt) print("M' =>", Mprime) print("H =>", H) print("DB =>", DB) print("dbmask=>", dbMask) print("masked=>", maskedDB) print("EM =>", EM) return EM
def verify(self, M, EM, emBits=None): ''' Verifies that EM is a correct encoding for M :Parameters: - M - the message to verify - EM - the encoded message :Return: true for 'consistent' or false for 'inconsistent' ''' if debug: print("PSS Decoding:") #Preconditions if emBits == None: emBits = 8 * len(EM) assert emBits >= 8* self.hLen + 8* self.sLen + 9, "Not enough emBits" emLen = int(math.ceil(emBits / 8.0)) assert len(EM) == emLen, "EM length not equivalent to bits provided" # assert len(M) < (2^61 -1), Message too long #Let mHash = Hash (M), an octet string of length hLen mHash = self.hashFn(M) #if emLen < hLen + sLen + 2, output 'inconsistent' and stop. if emLen < self.hLen + self.sLen + 2: if debug: print("emLen too short") return False #If the rightmost octet of EM does not have hexadecimal value 0xbc, output #'inconsistent' and stop. if EM[len(EM)-1:] != b'\xbc': if debug: print("0xbc not found") return False #Let maskedDB be the leftmost emLen - hLen - 1 octets of EM, and let H be the #next hLen octets. maskeDBlen = emLen - self.hLen - 1 maskedDB = Bytes(EM[:maskeDBlen]) H = EM[maskeDBlen:maskeDBlen+self.hLen] #If the leftmost 8emLen - emBits bits of the leftmost octet in maskedDB are not all #equal to zero, output 'inconsistent' and stop. numzeros = 8 * emLen - emBits bitmask = int('1'*numzeros + '0'*(8-numzeros), 2) _mask_check = maskedDB[0] if not py3: _mask_check = ord(_mask_check) if (_mask_check & bitmask != 0): if debug: print("right % bits of masked db not zero, found %" % (numzeros, bin(maskedDB[0]))) return False #Let dbMask = MGF (H, emLen - hLen - 1). masklen = emLen - self.hLen - 1 dbMask = MGF1(H, masklen, self.hashFn, self.hLen) #Let DB = maskedDB ^ dbMask. DB = maskedDB ^ dbMask #Set the leftmost 8emLen - emBits bits of the leftmost octet in DB to zero. numzeros = 8 * emLen - emBits bitmask = int('0'*numzeros + '1'*(8-numzeros), 2) ba = bytearray(DB) ba[0] &= bitmask DB = Bytes(ba) #If the emLen - hLen - sLen - 2 leftmost octets of DB are not zero zerolen = emLen - self.hLen - self.sLen - 2 if DB[:zerolen] != Bytes.fill(b'\x00', zerolen): if debug: print("DB did not start with % zero octets" % zerolen) return False #or if the octet at position emLen - hLen - sLen - 1 (the leftmost position is 'position 1') does not #have hexadecimal value 0x01, output 'inconsistent' and stop. _db_check = DB[zerolen] if not py3: _db_check = ord(_db_check) if _db_check != 0x01: if debug: print("DB did not have 0x01 at %s, found %s instead" % (zerolen,DB[zerolen])) return False #Let salt be the last sLen octets of DB. salt = DB[len(DB)-self.sLen:] #Let M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt ; mPrime = Bytes.fill(b'\x00', 8) + mHash + salt #Let H' = Hash (M'), an octet string of length hLen. HPrime = self.hashFn(mPrime) if debug: print("M =>", M) print("mHash =>", mHash) print("salt =>", salt) print("M' =>", mPrime) print("H =>", H) print("DB =>", DB) print("dbmask=>", dbMask) print("masked=>", maskedDB) print("EM =>", EM) #If H = H', output 'consistent'. Otherwise, output 'inconsistent'. return H == HPrime
def bytes2str(self, byteobj): return Bytes.decode(byteobj, 'utf-8')
def encode(self, M, emBits=None, salt=None): '''Encodes a message with PSS padding emLen will be set to the minimum allowed length if not explicitly set ''' # assert len(M) < (2^61 -1), Message too long #Let H' = Hash (M'), an octet string of length hLen. #Max length of output message if emBits is None: emBits = 8 * self.hLen + 8 * self.sLen + 9 #Round to the next byte emBits = int(math.ceil(emBits / 8.0)) * 8 assert emBits >= 8 * self.hLen + 8 * self.sLen + 9, "Not enough emBits" #Make sure the the message is long enough to be valid emLen = int(math.ceil(emBits / 8.0)) assert emLen >= self.hLen + self.sLen + 2, "emLen too small" if salt is None: if self.sLen > 0: salt = SecureRandomFactory.getInstance().getRandomBytes( self.sLen) else: salt = b'' assert len(salt) == self.sLen, "Salt wrong size" #Let M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt; eightzerobytes = Bytes.fill(b'\x00', 8) mHash = self.hashFn(M) Mprime = eightzerobytes + mHash + salt #Let H = Hash (M'), an octet string of length hLen. H = self.hashFn(Mprime) #Generate an octet string PS consisting of emLen - sLen - hLen - 2 zero octets. #The length of PS may be 0. pslen = emLen - self.sLen - self.hLen - 2 ps = Bytes.fill(b'\x00', pslen) #Let DB = PS || 0x01 || salt; DB is an octet string of length emLen - hLen - 1. DB = ps + Bytes(b'\x01') + salt #Let dbMask = MGF (H, emLen - hLen - 1). masklen = emLen - self.hLen - 1 dbMask = MGF1(H, masklen, self.hashFn, self.hLen) #Let maskedDB = DB ^ dbMask. maskedDB = DB ^ dbMask #Set the leftmost 8emLen - emBits bits of the leftmost octet in maskedDB to zero numzeros = 8 * emLen - emBits bitmask = int('0' * numzeros + '1' * (8 - numzeros), 2) ba = bytearray(maskedDB) ba[0] &= bitmask maskedDB = Bytes(ba) EM = maskedDB + H + Bytes(b'\xbc') if debug: print("PSS Encoding:") print("M =>", M) print("mHash =>", mHash) print("salt =>", salt) print("M' =>", Mprime) print("H =>", H) print("DB =>", DB) print("dbmask=>", dbMask) print("masked=>", maskedDB) print("EM =>", EM) return EM
def sha1(self, message): h = hashObj.copy() h.update(bytes(message)) return Bytes(h.digest())
def verify(self, M, EM, emBits=None): ''' Verifies that EM is a correct encoding for M :Parameters: - M - the message to verify - EM - the encoded message :Return: true for 'consistent' or false for 'inconsistent' ''' if debug: print("PSS Decoding:") #Preconditions if emBits == None: emBits = 8 * len(EM) assert emBits >= 8 * self.hLen + 8 * self.sLen + 9, "Not enough emBits" emLen = int(math.ceil(emBits / 8.0)) assert len(EM) == emLen, "EM length not equivalent to bits provided" # assert len(M) < (2^61 -1), Message too long #Let mHash = Hash (M), an octet string of length hLen mHash = self.hashFn(M) #if emLen < hLen + sLen + 2, output 'inconsistent' and stop. if emLen < self.hLen + self.sLen + 2: if debug: print("emLen too short") return False #If the rightmost octet of EM does not have hexadecimal value 0xbc, output #'inconsistent' and stop. if EM[len(EM) - 1:] != b'\xbc': if debug: print("0xbc not found") return False #Let maskedDB be the leftmost emLen - hLen - 1 octets of EM, and let H be the #next hLen octets. maskeDBlen = emLen - self.hLen - 1 maskedDB = Bytes(EM[:maskeDBlen]) H = EM[maskeDBlen:maskeDBlen + self.hLen] #If the leftmost 8emLen - emBits bits of the leftmost octet in maskedDB are not all #equal to zero, output 'inconsistent' and stop. numzeros = 8 * emLen - emBits bitmask = int('1' * numzeros + '0' * (8 - numzeros), 2) _mask_check = maskedDB[0] if not py3: _mask_check = ord(_mask_check) if (_mask_check & bitmask != 0): if debug: print("right % bits of masked db not zero, found %" % (numzeros, bin(maskedDB[0]))) return False #Let dbMask = MGF (H, emLen - hLen - 1). masklen = emLen - self.hLen - 1 dbMask = MGF1(H, masklen, self.hashFn, self.hLen) #Let DB = maskedDB ^ dbMask. DB = maskedDB ^ dbMask #Set the leftmost 8emLen - emBits bits of the leftmost octet in DB to zero. numzeros = 8 * emLen - emBits bitmask = int('0' * numzeros + '1' * (8 - numzeros), 2) ba = bytearray(DB) ba[0] &= bitmask DB = Bytes(ba) #If the emLen - hLen - sLen - 2 leftmost octets of DB are not zero zerolen = emLen - self.hLen - self.sLen - 2 if DB[:zerolen] != Bytes.fill(b'\x00', zerolen): if debug: print("DB did not start with % zero octets" % zerolen) return False #or if the octet at position emLen - hLen - sLen - 1 (the leftmost position is 'position 1') does not #have hexadecimal value 0x01, output 'inconsistent' and stop. _db_check = DB[zerolen] if not py3: _db_check = ord(_db_check) if _db_check != 0x01: if debug: print("DB did not have 0x01 at %s, found %s instead" % (zerolen, DB[zerolen])) return False #Let salt be the last sLen octets of DB. salt = DB[len(DB) - self.sLen:] #Let M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt ; mPrime = Bytes.fill(b'\x00', 8) + mHash + salt #Let H' = Hash (M'), an octet string of length hLen. HPrime = self.hashFn(mPrime) if debug: print("M =>", M) print("mHash =>", mHash) print("salt =>", salt) print("M' =>", mPrime) print("H =>", H) print("DB =>", DB) print("dbmask=>", dbMask) print("masked=>", maskedDB) print("EM =>", EM) #If H = H', output 'consistent'. Otherwise, output 'inconsistent'. return H == HPrime
def str2bytes(self, strobj): return Bytes(strobj, 'utf-8')