def ModExp(a, b, c):
    """Uses openssl, if available, to do a^b mod c where a,b,c are longs."""
    if not _FOUND_SSL:
        return pow(a, b, c)
    # convert arbitrary long args to bytes
    bytes_a = number.LongToBytes(a)
    bytes_b = number.LongToBytes(b)
    bytes_c = number.LongToBytes(c)

    # convert bytes to (pointer to) Bignums.
    bn_a = ssl.BN_bin2bn(bytes_a, len(bytes_a), 0)
    bn_b = ssl.BN_bin2bn(bytes_b, len(bytes_b), 0)
    bn_c = ssl.BN_bin2bn(bytes_c, len(bytes_c), 0)
    bn_result = ssl.BN_new()
    ctx = ssl.BN_CTX_new()

    # exponentiate and convert result to long
    ssl.BN_mod_exp(bn_result, bn_a, bn_b, bn_c, ctx)
    num_bytes_in_result = _NumBytesBn(bn_result)
    bytes_result = ctypes.create_string_buffer(num_bytes_in_result)
    ssl.BN_bn2bin(bn_result, bytes_result)
    long_result = number.BytesToLong(bytes_result.raw)

    # clean up
    ssl.BN_CTX_free(ctx)
    ssl.BN_free(bn_a)
    ssl.BN_free(bn_b)
    ssl.BN_free(bn_c)
    ssl.BN_free(bn_result)

    return long_result
Пример #2
0
 def testBytesToLong(self):
     self.assertEqual(205, number.BytesToLong('\xcd'))
     self.assertEqual(64, number.BytesToLong('\x00\x00\x00\x40'))
     self.assertEqual(64, number.BytesToLong('\x40'))
     self.assertEqual(4294967295 + 1,
                      number.BytesToLong('\x01\x00\x00\x00\x00'))
     self.assertEqual(
         18446744069414584320,
         number.BytesToLong('\xff\xff\xff\xff\x00\x00\x00\x00'))
     self.assertEqual(3, number.BytesToLong(struct.pack('>I', 3)))
     self.assertEqual(4294967303,
                      number.BytesToLong(struct.pack('>2I', 1, 7)))
     self.assertEqual(2**64, number.BytesToLong(struct.pack('>3I', 1, 0,
                                                            0)))
     self.assertEqual(
         2**160 + 2**128 + 2**96 + 2**64 + 2**32 + 7,
         number.BytesToLong(struct.pack('>6I', 1, 1, 1, 1, 1, 7)))
  def Decrypt(self, ciphertext):
    """Takes ciphertext and decrypts to a float.

    Args:
      ciphertext: a string which is an encrypted float, converted to bytes,
        and base64 encoded.

    Returns:
      decrypted float.

    Raises:
      ValueError: when ciphertext is not a string.
    """
    if not isinstance(ciphertext, str):
      raise ValueError('Expected type data str but got: %s' % type(ciphertext))
    return self._paillier.DecryptFloat(
        number.BytesToLong(base64.b64decode(ciphertext)))