def _check_encryption(self, rsaObj):
        plaintext = a2b_hex(self.plaintext)
        ciphertext = a2b_hex(self.ciphertext)

        # Test encryption
        new_ciphertext2 = rsaObj._encrypt(bytes_to_long(plaintext))
        self.assertEqual(bytes_to_long(ciphertext), new_ciphertext2)
Exemplo n.º 2
0
 def _test_signing(self, dsaObj):
     k = bytes_to_long(a2b_hex(self.k))
     m_hash = bytes_to_long(a2b_hex(self.m_hash))
     r = bytes_to_long(a2b_hex(self.r))
     s = bytes_to_long(a2b_hex(self.s))
     (r_out, s_out) = dsaObj._sign(m_hash, k)
     self.assertEqual((r, s), (r_out, s_out))
Exemplo n.º 3
0
    def _check_decryption(self, rsaObj):
        plaintext = bytes_to_long(a2b_hex(self.plaintext))
        ciphertext = bytes_to_long(a2b_hex(self.ciphertext))

        # Test plain decryption
        new_plaintext = rsaObj._decrypt(ciphertext)
        self.assertEqual(plaintext, new_plaintext)
Exemplo n.º 4
0
    def _check_public_key(self, dsaObj):
        k = bytes_to_long(a2b_hex(self.k))
        m_hash = bytes_to_long(a2b_hex(self.m_hash))

        # Check capabilities
        self.assertEqual(0, dsaObj.has_private())
        self.assertEqual(1, dsaObj.can_sign())
        self.assertEqual(0, dsaObj.can_encrypt())

        # Check that private parameters are all missing
        self.assertEqual(0, hasattr(dsaObj, 'x'))

        # Sanity check key data
        self.assertEqual(1, dsaObj.p > dsaObj.q)  # p > q
        self.assertEqual(160, size(dsaObj.q))  # size(q) == 160 bits
        self.assertEqual(0, (dsaObj.p - 1) % dsaObj.q)  # q is a divisor of p-1

        # Public-only key objects should raise an error when .sign() is called
        self.assertRaises(TypeError, dsaObj._sign, m_hash, k)

        # Check __eq__ and __ne__
        self.assertEqual(dsaObj.publickey() == dsaObj.publickey(),
                         True)  # assert_
        self.assertEqual(dsaObj.publickey() != dsaObj.publickey(),
                         False)  # failIf
Exemplo n.º 5
0
    def _check_encryption(self, rsaObj):
        plaintext = a2b_hex(self.plaintext)
        ciphertext = a2b_hex(self.ciphertext)

        # Test encryption
        new_ciphertext2 = rsaObj._encrypt(bytes_to_long(plaintext))
        self.assertEqual(bytes_to_long(ciphertext), new_ciphertext2)
Exemplo n.º 6
0
def readProductKey(verifyingPublicKeyInstance, licenseIdSize, productIdSize,
                   expirationTimeSize, hashSize, productKey):
    try:
        productKey = productKey.strip().replace('-', '').replace(' ', '')
        productKeyBytes = b32decode(
            (productKey + '=' * (-len(productKey) % 8)).encode('utf-8'))
        productKeyLong = bytes_to_long(productKeyBytes)
        longValue = verifyingPublicKeyInstance._encrypt(productKeyLong)
        bitString = ('{:0' + str(licenseIdSize + productIdSize +
                                 expirationTimeSize + hashSize * 8) +
                     'b}').format(longValue)
        licenseId = int(bitString[:licenseIdSize], 2)
        productId = int(bitString[licenseIdSize:licenseIdSize + productIdSize],
                        2)
        expirationTime = int(
            bitString[licenseIdSize + productIdSize:licenseIdSize +
                      productIdSize + expirationTimeSize], 2)
        computedHash = int(
            bitString[licenseIdSize + productIdSize + expirationTimeSize:], 2)

        shake = SHAKE256.new()
        shake.update(bitString[:licenseIdSize + productIdSize +
                               expirationTimeSize].encode('utf-8'))

        if computedHash != bytes_to_long(shake.read(hashSize)):
            raise InvalidProductKey()

        return licenseId, productId, expirationTime
    except:
        raise InvalidProductKey()
Exemplo n.º 7
0
 def _test_signing(self, dsaObj):
     k = bytes_to_long(a2b_hex(self.k))
     m_hash = bytes_to_long(a2b_hex(self.m_hash))
     r = bytes_to_long(a2b_hex(self.r))
     s = bytes_to_long(a2b_hex(self.s))
     (r_out, s_out) = dsaObj._sign(m_hash, k)
     self.assertEqual((r, s), (r_out, s_out))
    def _check_decryption(self, rsaObj):
        plaintext = bytes_to_long(a2b_hex(self.plaintext))
        ciphertext = bytes_to_long(a2b_hex(self.ciphertext))

        # Test plain decryption
        new_plaintext = rsaObj._decrypt(ciphertext)
        self.assertEqual(plaintext, new_plaintext)
def create_ref_keys():
    key_lines = load_file("ecc_p256.txt").splitlines()
    private_key_d = bytes_to_long(compact(key_lines[2:5]))
    public_key_xy = compact(key_lines[6:11])
    assert bord(public_key_xy[0]) == 4  # Uncompressed
    public_key_x = bytes_to_long(public_key_xy[1:33])
    public_key_y = bytes_to_long(public_key_xy[33:])

    return (ECC.construct(curve="P-256", d=private_key_d),
            ECC.construct(curve="P-256", point_x=public_key_x, point_y=public_key_y))
Exemplo n.º 10
0
def create_ref_keys():
    key_lines = load_file("ecc_p256.txt").splitlines()
    private_key_d = bytes_to_long(compact(key_lines[2:5]))
    public_key_xy = compact(key_lines[6:11])
    assert bord(public_key_xy[0]) == 4  # Uncompressed
    public_key_x = bytes_to_long(public_key_xy[1:33])
    public_key_y = bytes_to_long(public_key_xy[33:])

    return (ECC.construct(curve="P-256", d=private_key_d),
            ECC.construct(curve="P-256", point_x=public_key_x, point_y=public_key_y))
Exemplo n.º 11
0
    def xy(self):
        modulus_bytes = self.size_in_bytes()
        xb = bytearray(modulus_bytes)
        yb = bytearray(modulus_bytes)
        result = _ec_lib.ec_ws_get_xy(c_uint8_ptr(xb), c_uint8_ptr(yb),
                                      c_size_t(modulus_bytes),
                                      self._point.get())
        if result:
            raise ValueError("Error %d while encoding an EC point" % result)

        return (Integer(bytes_to_long(xb)), Integer(bytes_to_long(yb)))
Exemplo n.º 12
0
def create_ref_keys_p521():
    key_len = 66
    key_lines = load_file("ecc_p521.txt").splitlines()
    private_key_d = bytes_to_long(compact(key_lines[2:7]))
    public_key_xy = compact(key_lines[8:17])
    assert bord(public_key_xy[0]) == 4  # Uncompressed
    public_key_x = bytes_to_long(public_key_xy[1:key_len+1])
    public_key_y = bytes_to_long(public_key_xy[key_len+1:])

    return (ECC.construct(curve="P-521", d=private_key_d),
            ECC.construct(curve="P-521", point_x=public_key_x, point_y=public_key_y))
    def setUp(self):
        global RSA, Random, bytes_to_long
        from Cryptodome.PublicKey import RSA
        from Cryptodome import Random
        from Cryptodome.Util.number import bytes_to_long, inverse
        self.n = bytes_to_long(a2b_hex(self.modulus))
        self.p = bytes_to_long(a2b_hex(self.prime_factor))

        # Compute q, d, and u from n, e, and p
        self.q = self.n // self.p
        self.d = inverse(self.e, (self.p-1)*(self.q-1))
        self.u = inverse(self.p, self.q)    # u = e**-1 (mod q)

        self.rsa = RSA
Exemplo n.º 14
0
    def setUp(self):
        global RSA, Random, bytes_to_long
        from Cryptodome.PublicKey import RSA
        from Cryptodome import Random
        from Cryptodome.Util.number import bytes_to_long, inverse
        self.n = bytes_to_long(a2b_hex(self.modulus))
        self.p = bytes_to_long(a2b_hex(self.prime_factor))

        # Compute q, d, and u from n, e, and p
        self.q = self.n // self.p
        self.d = inverse(self.e, (self.p-1)*(self.q-1))
        self.u = inverse(self.p, self.q)    # u = e**-1 (mod q)

        self.rsa = RSA
Exemplo n.º 15
0
def flag2(s, cipher, mac, flag):
    bts = bytes_to_long(binascii.unhexlify(mac))
    m = bytes_to_long(pad(flag.encode(), 16))
    stream = m ^ bts
    newstr = flag[:-4] + 'getflag'
    nm = pad(newstr.encode(), 16)
    mac = binascii.hexlify(long_to_bytes(bytes_to_long(nm) ^ stream))
    s.sendlineafter('>', '1'.encode())
    s.sendlineafter(':', binascii.hexlify(newstr.encode()))
    message = s.recvline().decode().strip()
    s.sendlineafter('>', '3'.encode())
    s.sendlineafter(':', (message + '||' + mac.decode()).encode())
    flag2 = s.recvline().decode().strip()
    return flag2
Exemplo n.º 16
0
    def _check_public_key(self, rsaObj):
        ciphertext = a2b_hex(self.ciphertext)

        # Check capabilities
        self.assertEqual(0, rsaObj.has_private())

        # Check rsaObj.[ne] -> rsaObj.[ne] mapping
        self.assertEqual(rsaObj.n, rsaObj.n)
        self.assertEqual(rsaObj.e, rsaObj.e)

        # Check that private parameters are all missing
        self.assertEqual(0, hasattr(rsaObj, 'd'))
        self.assertEqual(0, hasattr(rsaObj, 'p'))
        self.assertEqual(0, hasattr(rsaObj, 'q'))
        self.assertEqual(0, hasattr(rsaObj, 'u'))

        # Sanity check key data
        self.assertEqual(1, rsaObj.e > 1)   # e > 1

        # Public keys should not be able to sign or decrypt
        self.assertRaises(TypeError, rsaObj._decrypt,
                bytes_to_long(ciphertext))

        # Check __eq__ and __ne__
        self.assertEqual(rsaObj.publickey() == rsaObj.publickey(),True) # assert_
        self.assertEqual(rsaObj.publickey() != rsaObj.publickey(),False) # failIf
Exemplo n.º 17
0
    def decrypt(self, init_value, ciphertext, auth_tag, auth_data=b''):
        if init_value >= (1 << 96):
            raise InvalidInputException('IV should be 96-bit')
        if auth_tag >= (1 << 128):
            raise InvalidInputException('Tag should be 128-bit')

        if auth_tag != self.__ghash(auth_data, ciphertext) ^ bytes_to_long(
                self._aes_ecb.encrypt(long_to_bytes(
                    (init_value << 32) | 1, 16))):
            raise InvalidTagException

        len_ciphertext = len(ciphertext)
        if len_ciphertext > 0:
            counter = Counter.new(nbits=32,
                                  prefix=long_to_bytes(init_value, 12),
                                  initial_value=2,
                                  allow_wraparound=True)
            aes_ctr = AES.new(self._master_key, AES.MODE_CTR, counter=counter)

            if 0 != len_ciphertext % 16:
                padded_ciphertext = ciphertext + \
                                    b'\x00' * (16 - len_ciphertext % 16)
            else:
                padded_ciphertext = ciphertext
            plaintext = aes_ctr.decrypt(padded_ciphertext)[:len_ciphertext]

        else:
            plaintext = b''

        return plaintext
    def sign(self, msg_hash):
        """Produce the PKCS#1 v1.5 signature of a message.

        This function is named ``RSASSA-PKCS1-V1_5-SIGN``;
        it is specified in section 8.2.1 of RFC3447.

        :Parameters:
          msg_hash : hash object
            This is an object created with to the `Cryptodome.Hash` module.
            It was used used to hash the message to sign.

        :Return: The signature encoded as a byte string.
        :Raise ValueError:
            If the RSA key is not long enough when combined with the given
            hash algorithm.
        :Raise TypeError:
            If the RSA key has no private half.
        """

        # See 8.2.1 in RFC3447
        modBits = Cryptodome.Util.number.size(self._key.n)
        k = ceil_div(modBits, 8)  # Convert from bits to bytes

        # Step 1
        em = _EMSA_PKCS1_V1_5_ENCODE(msg_hash, k)
        # Step 2a (OS2IP)
        em_int = bytes_to_long(em)
        # Step 2b (RSASP1)
        m_int = self._key._decrypt(em_int)
        # Step 2c (I2OSP)
        signature = long_to_bytes(m_int, k)
        return signature
Exemplo n.º 19
0
    def getrandbits(self, k):
        """Return an integer with k random bits."""

        if self._randfunc is None:
            self._randfunc = Random.new().read
        mask = (1 << k) - 1
        return mask & bytes_to_long(self._randfunc(ceil_div(k, 8)))
Exemplo n.º 20
0
    def decrypt(self, cipher):
        """
        :type cipher long
        :param cipher: 密文
        :return:
        """
        cipher = self.encoding_2_long(cipher, self.cipher_encoding)
        if self.d is not None:
            d = self.d
        else:
            d = inverse(self.e, (self.p - 1) * (self.q - 1))

        if self.n is not None:
            n = self.n
        else:
            n = self.p * self.q

        rsa = RSA.construct((n, self.e, d))
        if self.padding == 'PKCS1_OAEP':
            rsa = PKCS1_OAEP.new(rsa)
            plain = rsa.decrypt(long_to_bytes(cipher))
        elif self.padding == 'PKCS1_v1_5':
            rsa = PKCS1_v1_5.new(rsa)
            plain = rsa.decrypt(long_to_bytes(cipher), True)
        else:
            plain = pow(cipher, d, n)
            return self.long_2_encoding(plain, self.plain_encoding)

        plain = self.long_2_encoding(bytes_to_long(plain), self.plain_encoding)
        return plain
Exemplo n.º 21
0
def _encrypt(key, message):
    mod_bits = size(key.n)
    k = ceil_div(mod_bits, 8)
    m_len = len(message)

    # Step 1
    if m_len > k - 11:
        raise ValueError("Plaintext is too long.")
    # Step 2a
    ps = []
    while len(ps) != k - m_len - 3:
        new_byte = bchr(0xFF)
        if bord(new_byte[0]) == 0x00:
            continue
        ps.append(new_byte)
    ps = b("").join(ps)
    assert (len(ps) == k - m_len - 3)
    # Step 2b
    em = b('\x00\x01') + ps + bchr(0x00) + message
    # Step 3a (OS2IP)
    em_int = bytes_to_long(em)
    # Step 3b (RSAEP)
    if not 0 < em_int < key._n:
        raise ValueError("Plaintext too large")
    m_int = int(pow(Integer(em_int), key._d, key._n))
    # Step 3c (I2OSP)
    c = long_to_bytes(m_int, k)
    return c
Exemplo n.º 22
0
    def sign(self, msg_hash):
        """Produce the PKCS#1 v1.5 signature of a message.

        This function is named ``RSASSA-PKCS1-V1_5-SIGN``;
        it is specified in section 8.2.1 of RFC3447.

        :Parameters:
          msg_hash : hash object
            This is an object created with to the `Cryptodome.Hash` module.
            It was used used to hash the message to sign.

        :Return: The signature encoded as a byte string.
        :Raise ValueError:
            If the RSA key is not long enough when combined with the given
            hash algorithm.
        :Raise TypeError:
            If the RSA key has no private half.
        """

        # See 8.2.1 in RFC3447
        modBits = Cryptodome.Util.number.size(self._key.n)
        k = ceil_div(modBits,8) # Convert from bits to bytes

        # Step 1
        em = _EMSA_PKCS1_V1_5_ENCODE(msg_hash, k)
        # Step 2a (OS2IP)
        em_int = bytes_to_long(em)
        # Step 2b (RSASP1)
        m_int = self._key._decrypt(em_int)
        # Step 2c (I2OSP)
        signature = long_to_bytes(m_int, k)
        return signature
    def sign(self, msg_hash):
        """Create the PKCS#1 v1.5 signature of a message.

        This function is also called ``RSASSA-PKCS1-V1_5-SIGN`` and
        it is specified in
        `section 8.2.1 of RFC8017 <https://tools.ietf.org/html/rfc8017#page-36>`_.

        :parameter msg_hash:
            This is an object from the :mod:`Cryptodome.Hash` package.
            It has been used to digest the message to sign.
        :type msg_hash: hash object

        :return: the signature encoded as a *byte string*.
        :raise ValueError: if the RSA key is not long enough for the given hash algorithm.
        :raise TypeError: if the RSA key has no private half.
        """

        # See 8.2.1 in RFC3447
        modBits = Cryptodome.Util.number.size(self._key.n)
        k = ceil_div(modBits, 8)  # Convert from bits to bytes

        # Step 1
        em = _EMSA_PKCS1_V1_5_ENCODE(msg_hash, k)
        # Step 2a (OS2IP)
        em_int = bytes_to_long(em)
        # Step 2b (RSASP1)
        m_int = self._key._decrypt(em_int)
        # Step 2c (I2OSP)
        signature = long_to_bytes(m_int, k)
        return signature
Exemplo n.º 24
0
    def encrypt(self, plain):
        """
        :type plain long
        :param plain: 明文
        :return:
        """
        plain = self.encoding_2_long(plain, self.plain_encoding)
        rsa = RSA.construct((
            self.n,
            self.e,
        ))
        # 最佳非对称加密填充(OAEP)
        if self.padding == 'PKCS1_OAEP':
            rsa = PKCS1_OAEP.new(rsa)
            cipher = rsa.encrypt(long_to_bytes(plain))
        elif self.padding == 'PKCS1_v1_5':
            rsa = PKCS1_v1_5.new(rsa)
            cipher = rsa.encrypt(long_to_bytes(plain))
        else:
            cipher = pow(plain, self.e, self.n)
            return self.long_2_encoding(cipher, self.cipher_encoding)

        cipher = self.long_2_encoding(bytes_to_long(cipher),
                                      self.cipher_encoding)
        return cipher
Exemplo n.º 25
0
def get_each_aes(bytes_data, bytes_key, bytes_iv):
    results = []
    # ECB
    res = AES.new(bytes_key, AES.MODE_ECB).encrypt(bytes_data)
    results.append(("ECB", res))

    # no iv CTR
    res = AES.new(bytes_key, AES.MODE_CTR).encrypt(bytes_data)
    results.append(("CTR", res))

    c = Counter.new(128, initial_value=bytes_to_long(bytes_iv))
    res = AES.new(bytes_key, AES.MODE_CTR, counter=c).encrypt(bytes_data)
    results.append(("CTR-iv", res))

    res = AES.new(bytes_key, AES.MODE_CBC, bytes_iv).encrypt(bytes_data)
    results.append(("CBC", res))

    res = AES.new(bytes_key, AES.MODE_CFB, bytes_iv).encrypt(bytes_data)
    results.append(("CFB", res))

    res = AES.new(bytes_key, AES.MODE_OFB, bytes_iv).encrypt(bytes_data)
    results.append(("OFB", res))

    res = AES.new(bytes_key, AES.MODE_GCM, bytes_iv).encrypt(bytes_data)
    results.append(("GCM", res))

    # SIV keylen is restricted. prob not SIV.
    #    res = AES.new(bytes_key, AES.MODE_SIV, bytes_iv).encrypt(bytes_data)
    #    results.append(("SIV", res))

    # OCB takes a 15 byte nonce. don't think so.
    #    res = AES.new(bytes_key, AES.MODE_OCB, bytes_iv).encrypt(bytes_data)
    #    results.append(("OCB", res))

    return results
Exemplo n.º 26
0
Arquivo: RSA.py Projeto: macgia99/Code
def encrypt(msg,fl=Public_file):
    """
    we not have docstring here
    """
    encrypted = None
    try:
        f = open(fl,'r')
    except FileNotFoundError:
        print('Man! You not have file that have public key!')
        choice = None
        while choice == None:
            choice = input("Create(y/n)? ")
            if choice == 'y' or choice  == 'yes':
                key_menu()
            else:
                print("Warning! An error coming! Force Quit!!!!")
                raise SystemExit
    else:
        n = int(f.readline())
        e = int(f.readline())
        f.close()

        m = bytes_to_long(str(msg).encode('utf-8'))
        encrypted = pow(m,e,n)

    return encrypted
Exemplo n.º 27
0
def Enc_first(cheque):
    key = get_random_bytes(32)
    salt = get_random_bytes(16)

    ctr = Counter.new(128, initial_value=bytes_to_long(salt))

    cipher = AES.new(key, AES.MODE_CTR, counter=ctr)

    cipher_text = cipher.encrypt(bytes(json.dumps(cheque), 'utf-8'))

    HMAC_FIRST = b"BBuXaXBdHg+wLPjRJpf3N/NmLq5kuvzGQx3II15/j8o="
    mk = hmac.new(b64decode(HMAC_FIRST), salt + cipher_text, hashlib.sha512)

    dataDE = b64encode(mk.digest() + salt + cipher_text).decode('utf-8')

    recipient_key = RSA.import_key(open('1RSAcert.pem').read())
    cipher_rsa = PKCS1_OAEP.new(recipient_key)
    dataAB = b64encode(cipher_rsa.encrypt(key)).decode('utf-8')

    # шифрованный запрос
    return {
        "ab": dataAB,
        "de": dataDE,
        "kassaid": "122772",
        "kassatoken": "5373167af64a6e02cae10c2bf5c6a7e4",
        "check_type": "standart",
        "test": "0"
    }
Exemplo n.º 28
0
    def getrandbits(self, k):
        """Return an integer with k random bits."""

        if self._randfunc is None:
            self._randfunc = Random.new().read
        mask = (1 << k) - 1
        return mask & bytes_to_long(self._randfunc(ceil_div(k, 8)))
Exemplo n.º 29
0
    def sign(self, msg_hash):
        """Create the PKCS#1 v1.5 signature of a message.

        This function is also called ``RSASSA-PKCS1-V1_5-SIGN`` and
        it is specified in
        `section 8.2.1 of RFC8017 <https://tools.ietf.org/html/rfc8017#page-36>`_.

        :parameter msg_hash:
            This is an object from the :mod:`Cryptodome.Hash` package.
            It has been used to digest the message to sign.
        :type msg_hash: hash object

        :return: the signature encoded as a *byte string*.
        :raise ValueError: if the RSA key is not long enough for the given hash algorithm.
        :raise TypeError: if the RSA key has no private half.
        """

        # See 8.2.1 in RFC3447
        modBits = Cryptodome.Util.number.size(self._key.n)
        k = ceil_div(modBits,8) # Convert from bits to bytes

        # Step 1
        em = _EMSA_PKCS1_V1_5_ENCODE(msg_hash, k)
        # Step 2a (OS2IP)
        em_int = bytes_to_long(em)
        # Step 2b (RSASP1)
        m_int = self._key._decrypt(em_int)
        # Step 2c (I2OSP)
        signature = long_to_bytes(m_int, k)
        return signature
Exemplo n.º 30
0
 def test_repr(self):
     (y, g, p, q) = [
         bytes_to_long(a2b_hex(param))
         for param in (self.y, self.g, self.p, self.q)
     ]
     dsaObj = self.dsa.construct((y, g, p, q))
     repr(dsaObj)
Exemplo n.º 31
0
def extract_files(wak, out_dir, extract=True):
    if extract:
        out_dir = out_dir + "/"
        print("[+] Extracting to {}".format(out_dir))
        if not os.path.exists(out_dir):
            os.makedirs(out_dir)

    # multiprocessing this
    for f in wak.file_list:
        print("{:.50s}:[offs {:08X}][size {:08X}][pthl {:08X}]".format(
            f.path, f.offset, f.size, f.pathlen))
        if extract:
            fdata = wak.datawak_contents[f.offset:f.offset + f.size]
            f_iv = wak.prng.badprng_get16(0x165EC8F + f.tblidx)

            c = Counter.new(128, initial_value=bytes_to_long(f_iv))
            fdata_dec = AES.new(wak.prng.default_key, AES.MODE_CTR,
                                counter=c).decrypt(fdata)

            out_filepath = os.path.abspath(out_dir + f.path)
            out_filedir = os.path.split(out_filepath)[0]
            if not os.path.exists(out_filedir):
                os.makedirs(out_filedir)
            with open(out_filepath, 'wb') as outfile:
                outfile.write(fdata_dec)
    print("[+] Complete, iterated {} files.".format(len(wak.file_list)))
Exemplo n.º 32
0
    def decrypt(self, init_value, ciphertext, auth_tag, auth_data=b''):
        if init_value >= (1 << 96):
            raise InvalidInputException('IV should be 96-bit')
        if auth_tag >= (1 << 128):
            raise InvalidInputException('Tag should be 128-bit')

        if auth_tag != self.__ghash(
                auth_data, ciphertext) ^ bytes_to_long(
            self._aes_ecb.encrypt(
                long_to_bytes((init_value << 32) | 1, 16))):
            raise InvalidTagException

        len_ciphertext = len(ciphertext)
        if len_ciphertext > 0:
            counter = Counter.new(
                nbits=32,
                prefix=long_to_bytes(init_value, 12),
                initial_value=2,
                allow_wraparound=True)
            aes_ctr = AES.new(self._master_key, AES.MODE_CTR, counter=counter)

            if 0 != len_ciphertext % 16:
                padded_ciphertext = ciphertext + \
                                    b'\x00' * (16 - len_ciphertext % 16)
            else:
                padded_ciphertext = ciphertext
            plaintext = aes_ctr.decrypt(padded_ciphertext)[:len_ciphertext]

        else:
            plaintext = b''

        return plaintext
    def _check_public_key(self, rsaObj):
        ciphertext = a2b_hex(self.ciphertext)

        # Check capabilities
        self.assertEqual(0, rsaObj.has_private())

        # Check rsaObj.[ne] -> rsaObj.[ne] mapping
        self.assertEqual(rsaObj.n, rsaObj.n)
        self.assertEqual(rsaObj.e, rsaObj.e)

        # Check that private parameters are all missing
        self.assertEqual(0, hasattr(rsaObj, 'd'))
        self.assertEqual(0, hasattr(rsaObj, 'p'))
        self.assertEqual(0, hasattr(rsaObj, 'q'))
        self.assertEqual(0, hasattr(rsaObj, 'u'))

        # Sanity check key data
        self.assertEqual(1, rsaObj.e > 1)   # e > 1

        # Public keys should not be able to sign or decrypt
        self.assertRaises(TypeError, rsaObj._decrypt,
                bytes_to_long(ciphertext))

        # Check __eq__ and __ne__
        self.assertEqual(rsaObj.publickey() == rsaObj.publickey(),True) # assert_
        self.assertEqual(rsaObj.publickey() != rsaObj.publickey(),False) # failIf
Exemplo n.º 34
0
    def test_construct_bad_key5(self):
        (y, g, p, q, x) = [bytes_to_long(a2b_hex(param)) for param in (self.y, self.g, self.p, self.q, self.x)]
        tup = (y, g, p, q, x+1)
        self.assertRaises(ValueError, self.dsa.construct, tup)

        tup = (y, g, p, q, q+10)
        self.assertRaises(ValueError, self.dsa.construct, tup)
Exemplo n.º 35
0
    def encrypt(self, message):
        # See 7.2.1 in RFC8017
        modBits = Cryptodome.Util.number.size(self._key.n)
        k = ceil_div(modBits, 8)  # Convert from bits to bytes
        mLen = len(message)

        # Step 1
        if mLen > k - 11:
            raise ValueError("Plaintext is too long.")
        # Step 2a
        ps = []
        while len(ps) != k - mLen - 3:
            # Java 实现的时候是填充为 \xff,所以每次加密相同明文,得到的密文是一样的
            ps.append(b'\xff')
        ps = b"".join(ps)
        assert (len(ps) == k - mLen - 3)
        # Step 2b
        # pkcs#1_v115 是 x00x02,Java里面是\x00\x01
        em = b'\x00\x01' + ps + b'\x00' + _copy_bytes(None, None, message)
        # Step 3a (OS2IP)
        em_int = bytes_to_long(em)
        # Step 3b (RSAEP)
        m_int = self._key._encrypt(em_int)
        # Step 3c (I2OSP)
        c = long_to_bytes(m_int, k)
        return c
Exemplo n.º 36
0
Arquivo: ec.py Projeto: na1pir/hbc
def check_ecdsa(q,r,s,sha):

	q = Point(q)
	r = bytes_to_long(r)
	s = bytes_to_long(s)
	e = bytes_to_long(sha)

	s_inv = bn_inv(s,ec_N)

	w1 = (e*s_inv)%ec_N
	w2 = (r*s_inv)%ec_N

	r1 = w1 * ec_G + w2 * q

	rx = r1.x.tobignum()%ec_N

	return rx == r
Exemplo n.º 37
0
 def test_construct_4tuple(self):
     """DSA (default implementation) constructed key (4-tuple)"""
     (y, g, p, q) = [
         bytes_to_long(a2b_hex(param))
         for param in (self.y, self.g, self.p, self.q)
     ]
     dsaObj = self.dsa.construct((y, g, p, q))
     self._test_verification(dsaObj)
Exemplo n.º 38
0
    def grow(self, seed, layer):
        exp = pow(self.d, layer, self.phi)
        seed = bytes_to_long(seed)
        if seed >= self.n or seed < 0:
            raise Exception

        onion = pow(seed, exp, self.n)
        return long_to_bytes(onion)
Exemplo n.º 39
0
 def sign(self, message):
     if not self.keyObject:
         raise ValueError('key object is not exist')
     h = SHA1.new(message)
     signature_bytes = pkcs1_15.new(self.keyObject).sign(h)
     signature_int = number.bytes_to_long(signature_bytes)
     signature = str(signature_int)
     return signature
Exemplo n.º 40
0
Arquivo: ec.py Projeto: na1pir/hbc
def gen_priv_key():
	k = open("/dev/random","rb").read(30)
	if len(k) != 30:
		raise Exception("Failed to get random data")

	k = bytes_to_long(k)
	k = k % ec_N
	return long_to_bytes(k,30)
Exemplo n.º 41
0
    def test_construct_bad_key4(self):
        (y, g, p, q) = [bytes_to_long(a2b_hex(param)) for param in (self.y, self.g, self.p, self.q)]
        tup = (y, g, p+1, q)
        self.assertRaises(ValueError, self.dsa.construct, tup)

        tup = (y, g, p, q+1)
        self.assertRaises(ValueError, self.dsa.construct, tup)

        tup = (y, 1L, p, q)
        self.assertRaises(ValueError, self.dsa.construct, tup)
Exemplo n.º 42
0
    def _create_ctr_cipher(self, mac_tag):
        """Create a new CTR cipher from the MAC in SIV mode"""

        tag_int = bytes_to_long(mac_tag)
        return self._factory.new(
                    self._subkey_cipher,
                    self._factory.MODE_CTR,
                    initial_value=tag_int ^ (tag_int & 0x8000000080000000L),
                    nonce=b(""),
                    **self._cipher_params)
Exemplo n.º 43
0
    def encrypt(self, message):
        """Produce the PKCS#1 OAEP encryption of a message.

        This function is named ``RSAES-OAEP-ENCRYPT``, and is specified in
        section 7.1.1 of RFC3447.

        :Parameters:
         message : byte string
                The message to encrypt, also known as plaintext. It can be of
                variable length, but not longer than the RSA modulus (in bytes)
                minus 2, minus twice the hash output size.

        :Return: A byte string, the ciphertext in which the message is encrypted.
            It is as long as the RSA modulus (in bytes).
        :Raise ValueError:
            If the RSA key length is not sufficiently long to deal with the given
            message.
        """
        # TODO: Verify the key is RSA

        # See 7.1.1 in RFC3447
        modBits = Cryptodome.Util.number.size(self._key.n)
        k = ceil_div(modBits,8) # Convert from bits to bytes
        hLen = self._hashObj.digest_size
        mLen = len(message)

        # Step 1b
        ps_len = k-mLen-2*hLen-2
        if ps_len<0:
            raise ValueError("Plaintext is too long.")
        # Step 2a
        lHash = self._hashObj.new(self._label).digest()
        # Step 2b
        ps = bchr(0x00)*ps_len
        # Step 2c
        db = lHash + ps + bchr(0x01) + message
        # Step 2d
        ros = self._randfunc(hLen)
        # Step 2e
        dbMask = self._mgf(ros, k-hLen-1)
        # Step 2f
        maskedDB = strxor(db, dbMask)
        # Step 2g
        seedMask = self._mgf(maskedDB, hLen)
        # Step 2h
        maskedSeed = strxor(ros, seedMask)
        # Step 2i
        em = bchr(0x00) + maskedSeed + maskedDB
        # Step 3a (OS2IP)
        em_int = bytes_to_long(em)
        # Step 3b (RSAEP)
        m_int = self._key._encrypt(em_int)
        # Step 3c (I2OSP)
        c = long_to_bytes(m_int, k)
        return c
Exemplo n.º 44
0
    def verify(self, msg_hash, signature):
        """Verify that a certain PKCS#1 v1.5 signature is valid.

        This method checks if the message really originates from someone
        that holds the RSA private key.
        really signed the message.

        This function is named ``RSASSA-PKCS1-V1_5-VERIFY``;
        it is specified in section 8.2.2 of RFC3447.

        :Parameters:
          msg_hash : hash object
            The hash that was carried out over the message. This is an object
            belonging to the `Cryptodome.Hash` module.
          signature : byte string
            The signature that needs to be validated.
        :Raise ValueError:
            if the signature is not valid.
        """

        # See 8.2.2 in RFC3447
        modBits = Cryptodome.Util.number.size(self._key.n)
        k = ceil_div(modBits, 8) # Convert from bits to bytes

        # Step 1
        if len(signature) != k:
            raise ValueError("Invalid signature")
        # Step 2a (O2SIP)
        signature_int = bytes_to_long(signature)
        # Step 2b (RSAVP1)
        em_int = self._key._encrypt(signature_int)
        # Step 2c (I2OSP)
        em1 = long_to_bytes(em_int, k)
        # Step 3
        try:
            possible_em1 = [ _EMSA_PKCS1_V1_5_ENCODE(msg_hash, k, True) ]
            # MD2/4/5 hashes always require NULL params in AlgorithmIdentifier.
            # For all others, it is optional.
            try:
                algorithm_is_md = msg_hash.oid.startswith('1.2.840.113549.2.')
            except AttributeError:
                algorithm_is_md = False
            if not algorithm_is_md:  # MD2/MD4/MD5
                possible_em1.append(_EMSA_PKCS1_V1_5_ENCODE(msg_hash, k, False))
        except ValueError:
            raise ValueError("Invalid signature")
        # Step 4
        # By comparing the full encodings (as opposed to checking each
        # of its components one at a time) we avoid attacks to the padding
        # scheme like Bleichenbacher's (see http://www.mail-archive.com/[email protected]/msg06537).
        #
        if em1 not in possible_em1:
            raise ValueError("Invalid signature")
        pass
Exemplo n.º 45
0
    def _create_ctr_cipher(self, v):
        """Create a new CTR cipher from V in SIV mode"""

        v_int = bytes_to_long(v)
        q = v_int & 0xFFFFFFFFFFFFFFFF7FFFFFFF7FFFFFFF
        return self._factory.new(
                    self._subkey_cipher,
                    self._factory.MODE_CTR,
                    initial_value=q,
                    nonce=b"",
                    **self._cipher_params)
Exemplo n.º 46
0
    def _exercise_primitive(self, rsaObj):
        # Since we're using a randomly-generated key, we can't check the test
        # vector, but we can make sure encryption and decryption are inverse
        # operations.
        ciphertext = bytes_to_long(a2b_hex(self.ciphertext))

        # Test decryption
        plaintext = rsaObj._decrypt(ciphertext)

        # Test encryption (2 arguments)
        new_ciphertext2 = rsaObj._encrypt(plaintext)
        self.assertEqual(ciphertext, new_ciphertext2)
Exemplo n.º 47
0
        def _decodeLen(self, s):
                """Decode DER length octets from a file."""

                length = s.read_byte()
                if length <= 127:
                        return length
                payloadLength = bytes_to_long(s.read(length & 0x7F))
                # According to DER (but not BER) the long form is used
                # only when the length doesn't fit into 7 bits.
                if payloadLength <= 127:
                        raise ValueError("Not a DER length tag (but still valid BER).")
                return payloadLength
Exemplo n.º 48
0
    def _check_public_key(self, dsaObj):
        k = bytes_to_long(a2b_hex(self.k))
        m_hash = bytes_to_long(a2b_hex(self.m_hash))

        # Check capabilities
        self.assertEqual(0, dsaObj.has_private())
        self.assertEqual(1, dsaObj.can_sign())
        self.assertEqual(0, dsaObj.can_encrypt())

        # Check that private parameters are all missing
        self.assertEqual(0, hasattr(dsaObj, 'x'))

        # Sanity check key data
        self.assertEqual(1, dsaObj.p > dsaObj.q)            # p > q
        self.assertEqual(160, size(dsaObj.q))               # size(q) == 160 bits
        self.assertEqual(0, (dsaObj.p - 1) % dsaObj.q)      # q is a divisor of p-1

        # Public-only key objects should raise an error when .sign() is called
        self.assertRaises(TypeError, dsaObj._sign, m_hash, k)

        # Check __eq__ and __ne__
        self.assertEqual(dsaObj.publickey() == dsaObj.publickey(),True) # assert_
        self.assertEqual(dsaObj.publickey() != dsaObj.publickey(),False) # failIf
 def convert_tv(self, tv, as_longs=0):
     """Convert a test vector from textual form (hexadecimal ascii
     to either integers or byte strings."""
     key_comps = 'p','g','y','x'
     tv2 = {}
     for c in tv.keys():
         tv2[c] = a2b_hex(tv[c])
         if as_longs or c in key_comps or c in ('sig1','sig2'):
             tv2[c] = bytes_to_long(tv2[c])
     tv2['key']=[]
     for c in key_comps:
         tv2['key'] += [tv2[c]]
         del tv2[c]
     return tv2
Exemplo n.º 50
0
    def enc_setup(self, enc_alg, msg, auth_data, key=None, iv=""):
        """ Encrypt JWE content.

        :param enc_alg: The JWE "enc" value specifying the encryption algorithm
        :param msg: The plain text message
        :param auth_data: Additional authenticated data
        :param key: Key (CEK)
        :return: Tuple (ciphertext, tag), both as bytes
        """

        key, iv = self._generate_key_and_iv(enc_alg, key, iv)

        if enc_alg in ["A192GCM", "A128GCM", "A256GCM"]:
            gcm = AES_GCM(bytes_to_long(key))
            ctxt, tag = gcm.encrypt(bytes_to_long(iv), msg, auth_data)
            tag = long_to_bytes(tag)
        elif enc_alg in ["A128CBC-HS256", "A192CBC-HS384", "A256CBC-HS512"]:
            assert enc_alg in SUPPORTED["enc"]
            ctxt, tag = aes_cbc_hmac_encrypt(key, iv, auth_data, msg)
        else:
            raise NotSupportedAlgorithm(enc_alg)

        return ctxt, tag, key
Exemplo n.º 51
0
        def testVerify2(self):
                # Verify that decryption fails if ciphertext is not as long as
                # RSA modulus
                cipher = PKCS.new(self.key1024)
                self.assertRaises(ValueError, cipher.decrypt, '\x00'*127, "---")
                self.assertRaises(ValueError, cipher.decrypt, '\x00'*129, "---")

                # Verify that decryption fails if there are less then 8 non-zero padding
                # bytes
                pt = b('\x00\x02' + '\xFF'*7 + '\x00' + '\x45'*118)
                pt_int = bytes_to_long(pt)
                ct_int = self.key1024._encrypt(pt_int)
                ct = long_to_bytes(ct_int, 128)
                self.assertEqual("---", cipher.decrypt(ct, "---"))
Exemplo n.º 52
0
    def __init__(self, encoded_value):
        """Initialize the element to a certain value.

        The value passed as parameter is internally encoded as
        a 128-bit integer, where each bit represents a polynomial
        coefficient. The LSB is the constant coefficient.
        """

        if isinstance(encoded_value, (int, long)):
            self._value = encoded_value
        elif len(encoded_value) == 16:
            self._value = bytes_to_long(encoded_value)
        else:
            raise ValueError("The encoded value must be an integer or a 16 byte string")
Exemplo n.º 53
0
    def _decrypt(enc, key, ctxt, auth_data, iv, tag):
        """ Decrypt JWE content.

        :param enc: The JWE "enc" value specifying the encryption algorithm
        :param key: Key (CEK)
        :param iv : Initialization vector
        :param auth_data: Additional authenticated data (AAD)
        :param ctxt : Ciphertext
        :param tag: Authentication tag
        :return: plain text message or None if decryption failed
        """
        if enc in ["A128GCM", "A192GCM", "A256GCM"]:
            gcm = AES_GCM(bytes_to_long(key))
            try:
                text = gcm.decrypt(bytes_to_long(iv), ctxt, bytes_to_long(tag),
                                   auth_data)
                return text, True
            except DecryptionFailed:
                return None, False
        elif enc in ["A128CBC-HS256", "A192CBC-HS384", "A256CBC-HS512"]:
            return aes_cbc_hmac_decrypt(key, iv, auth_data, ctxt, tag)
        else:
            raise Exception("Unsupported encryption algorithm %s" % enc)
Exemplo n.º 54
0
    def sign(self, msg_hash):
        """Produce the PKCS#1 PSS signature of a message.

        This function is named ``RSASSA-PSS-SIGN``, and is specified in
        section 8.1.1 of RFC3447.

        :Parameters:
          msg_hash : hash object
            The hash that was carried out over the message. This is an object
            belonging to the `Cryptodome.Hash` module.

        :Return: The PSS signature encoded as a byte string.
        :Raise ValueError:
            If the RSA key length is not sufficiently long to deal
            with the given hash algorithm.
        :Raise TypeError:
            If the RSA key has no private half.

        :attention: Modify the salt length and the mask generation
                    function only if you know what you are doing.
                    The receiver must use the same parameters too.
        """

        # Set defaults for salt length and mask generation function
        if self._saltLen is None:
            sLen = msg_hash.digest_size
        else:
            sLen = self._saltLen

        if self._mgfunc is None:
            mgf = lambda x, y: MGF1(x, y, msg_hash)
        else:
            mgf = self._mgfunc

        modBits = Cryptodome.Util.number.size(self._key.n)

        # See 8.1.1 in RFC3447
        k = ceil_div(modBits, 8)  # k is length in bytes of the modulus
        # Step 1
        em = _EMSA_PSS_ENCODE(msg_hash, modBits-1, self._randfunc, mgf, sLen)
        # Step 2a (OS2IP)
        em_int = bytes_to_long(em)
        # Step 2b (RSASP1)
        m_int = self._key._decrypt(em_int)
        # Step 2c (I2OSP)
        signature = long_to_bytes(m_int, k)
        return signature
Exemplo n.º 55
0
    def __init__(self, factory, key, nonce, mac_len, cipher_params):
        """EAX cipher mode"""

        self.block_size = factory.block_size
        """The block size of the underlying cipher, in bytes."""

        self.nonce = _copy_bytes(None, None, nonce)
        """The nonce originally used to create the object."""

        self._mac_len = mac_len
        self._mac_tag = None  # Cache for MAC tag

        # Allowed transitions after initialization
        self._next = [self.update, self.encrypt, self.decrypt,
                      self.digest, self.verify]

        # MAC tag length
        if not (4 <= self._mac_len <= self.block_size):
            raise ValueError("Parameter 'mac_len' must not be larger than %d"
                             % self.block_size)

        # Nonce cannot be empty and must be a byte string
        if len(self.nonce) == 0:
            raise ValueError("Nonce cannot be empty in EAX mode")
        if isinstance(nonce, unicode):
            raise TypeError("nonce must be a byte string")

        self._omac = [
                CMAC.new(key,
                         b'\x00' * (self.block_size - 1) + struct.pack('B', i),
                         ciphermod=factory,
                         cipher_params=cipher_params)
                for i in xrange(0, 3)
                ]

        # Compute MAC of nonce
        self._omac[0].update(self.nonce)
        self._signer = self._omac[1]

        # MAC of the nonce is also the initial counter for CTR encryption
        counter_int = bytes_to_long(self._omac[0].digest())
        self._cipher = factory.new(key,
                                   factory.MODE_CTR,
                                   initial_value=counter_int,
                                   nonce=b"",
                                   **cipher_params)
Exemplo n.º 56
0
    def encrypt(self, message):
        """Produce the PKCS#1 v1.5 encryption of a message.

        This function is named ``RSAES-PKCS1-V1_5-ENCRYPT``, and is specified in
        section 7.2.1 of RFC3447.
        For a complete example see `Cryptodome.Cipher.PKCS1_v1_5`.

        :Parameters:
         message : byte string
                The message to encrypt, also known as plaintext. It can be of
                variable length, but not longer than the RSA modulus (in bytes) minus 11.

        :Return: A byte string, the ciphertext in which the message is encrypted.
            It is as long as the RSA modulus (in bytes).
        :Raise ValueError:
            If the RSA key length is not sufficiently long to deal with the given
            message.

        """

        # See 7.2.1 in RFC3447
        modBits = Cryptodome.Util.number.size(self._key.n)
        k = ceil_div(modBits,8) # Convert from bits to bytes
        mLen = len(message)

        # Step 1
        if mLen > k-11:
            raise ValueError("Plaintext is too long.")
        # Step 2a
        ps = []
        while len(ps) != k - mLen - 3:
            new_byte = self._randfunc(1)
            if bord(new_byte[0]) == 0x00:
                continue
            ps.append(new_byte)
        ps = b("").join(ps)
        assert(len(ps) == k - mLen - 3)
        # Step 2b
        em = b('\x00\x02') + ps + bchr(0x00) + message
        # Step 3a (OS2IP)
        em_int = bytes_to_long(em)
        # Step 3b (RSAEP)
        m_int = self._key._encrypt(em_int)
        # Step 3c (I2OSP)
        c = long_to_bytes(m_int, k)
        return c
Exemplo n.º 57
0
    def verify(self, msg_hash, signature):
        """Verify that a certain PKCS#1 PSS signature is authentic.

        This function checks if the party holding the private half
        of the given RSA key has really signed the message.

        This function is called ``RSASSA-PSS-VERIFY``, and is specified
        in section 8.1.2 of RFC3447.

        :Parameters:
          msg_hash : hash object
            The cryptographic hash computed over the message.
            This is an object belonging to the `Cryptodome.Hash` module.
          signature : byte string
            The signature that needs to be validated.

        :Raise ValueError:
            if the signature is incorrect.
        """

        # Set defaults for salt length and mask generation function
        if self._saltLen is None:
            sLen = msg_hash.digest_size
        else:
            sLen = self._saltLen
        if self._mgfunc:
            mgf = self._mgfunc
        else:
            mgf = lambda x, y: MGF1(x, y, msg_hash)

        modBits = Cryptodome.Util.number.size(self._key.n)

        # See 8.1.2 in RFC3447
        k = ceil_div(modBits, 8)  # Convert from bits to bytes
        # Step 1
        if len(signature) != k:
            raise ValueError("Incorrect signature")
        # Step 2a (O2SIP)
        signature_int = bytes_to_long(signature)
        # Step 2b (RSAVP1)
        em_int = self._key._encrypt(signature_int)
        # Step 2c (I2OSP)
        emLen = ceil_div(modBits - 1, 8)
        em = long_to_bytes(em_int, emLen)
        # Step 3/4
        _EMSA_PSS_VERIFY(msg_hash, em, modBits-1, mgf, sLen)
Exemplo n.º 58
0
    def encrypt(self, message):
        """Produce the PKCS#1 v1.5 encryption of a message.

        This function is named ``RSAES-PKCS1-V1_5-ENCRYPT``, and it is specified in
        `section 7.2.1 of RFC8017
        <https://tools.ietf.org/html/rfc8017#page-28>`_.

        :param message:
            The message to encrypt, also known as plaintext. It can be of
            variable length, but not longer than the RSA modulus (in bytes) minus 11.
        :type message: bytes/bytearray/memoryview

        :Returns: A byte string, the ciphertext in which the message is encrypted.
            It is as long as the RSA modulus (in bytes).

        :Raises ValueError:
            If the RSA key length is not sufficiently long to deal with the given
            message.
        """

        # See 7.2.1 in RFC8017
        modBits = Cryptodome.Util.number.size(self._key.n)
        k = ceil_div(modBits,8) # Convert from bits to bytes
        mLen = len(message)

        # Step 1
        if mLen > k - 11:
            raise ValueError("Plaintext is too long.")
        # Step 2a
        ps = []
        while len(ps) != k - mLen - 3:
            new_byte = self._randfunc(1)
            if bord(new_byte[0]) == 0x00:
                continue
            ps.append(new_byte)
        ps = b"".join(ps)
        assert(len(ps) == k - mLen - 3)
        # Step 2b
        em = b'\x00\x02' + ps + b'\x00' + _copy_bytes(None, None, message)
        # Step 3a (OS2IP)
        em_int = bytes_to_long(em)
        # Step 3b (RSAEP)
        m_int = self._key._encrypt(em_int)
        # Step 3c (I2OSP)
        c = long_to_bytes(m_int, k)
        return c
Exemplo n.º 59
0
    def inplace_pow(self, exponent, modulus=None):
        exp_value = int(exponent)
        if exp_value < 0:
            raise ValueError("Exponent must not be negative")

        # No modular reduction
        if modulus is None:
            self._value = pow(self._value, exp_value)
            return self

        # With modular reduction
        mod_value = int(modulus)
        if mod_value < 0:
            raise ValueError("Modulus must be positive")
        if mod_value == 0:
            raise ZeroDivisionError("Modulus cannot be zero")

        # C extension only works with odd moduli
        if (mod_value & 1) == 0:
            self._value = pow(self._value, exp_value, mod_value)
            return self

        max_len = len(long_to_bytes(max(self._value, exp_value, mod_value)))

        base_b    = long_to_bytes(self._value, max_len)
        exp_b     = long_to_bytes(exp_value, max_len)
        modulus_b = long_to_bytes(mod_value, max_len)

        out = create_string_buffer(max_len)

        error = _raw_montgomery.monty_pow(
                    base_b,
                    exp_b,
                    modulus_b,
                    out,
                    c_size_t(max_len),
                    c_ulonglong(getrandbits(64))
                    )

        if error:
            raise ValueError("monty_pow failed with error: %d" % error)

        result = bytes_to_long(get_raw_buffer(out))
        self._value = result
        return self