#![doc(html_root_url = "https://docs.rs/abcrypt-py/0.1.0/")]
#![forbid(unsafe_code)]
#![deny(missing_debug_implementations, missing_docs)]
#![warn(rust_2018_idioms)]
#![warn(clippy::cargo, clippy::nursery, clippy::pedantic)]
#![allow(clippy::redundant_pub_crate)]
mod error;
mod params;
use std::borrow::Cow;
use abcrypt::argon2;
use pyo3::{
exceptions::PyValueError, pyclass, pyfunction, pymethods, pymodule, types::PyModule,
wrap_pyfunction, PyResult, Python,
};
pub use crate::params::Params;
use crate::error::Error;
#[derive(Clone, Copy, Debug)]
#[pyclass]
pub struct Format;
#[pymethods]
impl Format {
#[classattr]
pub const HEADER_SIZE: usize = abcrypt::HEADER_SIZE;
#[classattr]
pub const TAG_SIZE: usize = abcrypt::TAG_SIZE;
}
#[pyfunction]
pub fn encrypt<'a>(plaintext: &[u8], passphrase: &[u8]) -> PyResult<Cow<'a, [u8]>> {
let ciphertext = abcrypt::encrypt(plaintext, passphrase).map_err(Error::from)?;
Ok(ciphertext.into())
}
#[pyfunction]
pub fn encrypt_with_params<'a>(
plaintext: &[u8],
passphrase: &[u8],
memory_cost: u32,
time_cost: u32,
parallelism: u32,
) -> PyResult<Cow<'a, [u8]>> {
let params = argon2::Params::new(memory_cost, time_cost, parallelism, None)
.map_err(|e| PyValueError::new_err(e.to_string()))?;
let ciphertext =
abcrypt::encrypt_with_params(plaintext, passphrase, params).map_err(Error::from)?;
Ok(ciphertext.into())
}
#[pyfunction]
pub fn decrypt<'a>(ciphertext: &[u8], passphrase: &[u8]) -> PyResult<Cow<'a, [u8]>> {
let plaintext = abcrypt::decrypt(ciphertext, passphrase).map_err(Error::from)?;
Ok(plaintext.into())
}
#[pymodule]
fn abcrypt_py(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
m.add_function(wrap_pyfunction!(encrypt, m)?)?;
m.add_function(wrap_pyfunction!(encrypt_with_params, m)?)?;
m.add_function(wrap_pyfunction!(decrypt, m)?)?;
m.add_class::<Params>()?;
m.add_class::<Format>()?;
Ok(())
}