Ejemplo n.º 1
0
    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
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
    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
Ejemplo n.º 4
0
    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
Ejemplo n.º 5
0
    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
Ejemplo n.º 6
0
    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
Ejemplo n.º 7
0
    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
Ejemplo n.º 8
0
    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
Ejemplo n.º 9
0
    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
Ejemplo n.º 10
0
    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