1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// SPDX-FileCopyrightText: 2022 Shun Sakai
//
// SPDX-License-Identifier: Apache-2.0 OR MIT

//! The `scryptenc` crate is an implementation of the scrypt encrypted data
//! format.
//!
//! The format is defined [here][specification-url].
//!
//! # Examples
//!
//! ## Encrypt and decrypt
//!
//! ```
//! # #[cfg(feature = "alloc")]
//! # {
//! use scryptenc::{scrypt::Params, Decryptor, Encryptor};
//!
//! let data = b"Hello, world!\n";
//! let passphrase = "passphrase";
//!
//! // Encrypt `data` using `passphrase`.
//! let params = Params::new(10, 8, 1, Params::RECOMMENDED_LEN).unwrap();
//! let ciphertext = Encryptor::with_params(data, passphrase, params).encrypt_to_vec();
//! assert_ne!(ciphertext, data);
//!
//! // And decrypt it back.
//! let plaintext = Decryptor::new(&ciphertext, passphrase)
//!     .and_then(|c| c.decrypt_to_vec())
//!     .unwrap();
//! assert_eq!(plaintext, data);
//! # }
//! ```
//!
//! ### `no_std` support
//!
//! This crate supports `no_std` mode and can be used without the `alloc` crate
//! and the `std` crate. Disables the `default` feature to enable this.
//!
//! ```
//! use scryptenc::{scrypt::Params, Decryptor, Encryptor};
//!
//! let data = b"Hello, world!\n";
//! let passphrase = "passphrase";
//!
//! // Encrypt `data` using `passphrase`.
//! let params = Params::new(10, 8, 1, Params::RECOMMENDED_LEN).unwrap();
//! let cipher = Encryptor::with_params(data, passphrase, params);
//! let mut buf = [u8::default(); 142];
//! cipher.encrypt(&mut buf);
//! assert_ne!(buf, data.as_slice());
//!
//! // And decrypt it back.
//! let cipher = Decryptor::new(&buf, passphrase).unwrap();
//! let mut buf = [u8::default(); 14];
//! cipher.decrypt(&mut buf).unwrap();
//! assert_eq!(buf, data.as_slice());
//! ```
//!
//! ## Extract the scrypt parameters in the encrypted data
//!
//! ```
//! # #[cfg(feature = "alloc")]
//! # {
//! use scryptenc::{scrypt, Encryptor};
//!
//! let data = b"Hello, world!\n";
//! let passphrase = "passphrase";
//!
//! // Encrypt `data` using `passphrase`.
//! let ciphertext = Encryptor::new(data, passphrase).encrypt_to_vec();
//!
//! // And extract the scrypt parameters from it.
//! let params = scryptenc::Params::new(ciphertext).unwrap();
//! assert_eq!(params.log_n(), scrypt::Params::RECOMMENDED_LOG_N);
//! assert_eq!(params.n(), 1 << scrypt::Params::RECOMMENDED_LOG_N);
//! assert_eq!(params.r(), scrypt::Params::RECOMMENDED_R);
//! assert_eq!(params.p(), scrypt::Params::RECOMMENDED_P);
//! # }
//! ```
//!
//! [specification-url]: https://github.com/Tarsnap/scrypt/blob/1.3.1/FORMAT

#![doc(html_root_url = "https://docs.rs/scryptenc/0.8.1/")]
#![no_std]
#![cfg_attr(doc_cfg, feature(doc_auto_cfg, doc_cfg))]
// Lint levels of rustc.
#![forbid(unsafe_code)]
#![deny(missing_debug_implementations, missing_docs)]
#![warn(rust_2018_idioms)]
// Lint levels of Clippy.
#![warn(clippy::cargo, clippy::nursery, clippy::pedantic)]

#[cfg(feature = "alloc")]
#[macro_use]
extern crate alloc;
#[cfg(feature = "std")]
extern crate std;

mod decrypt;
mod encrypt;
mod error;
mod format;
mod params;

pub use hmac;
pub use scrypt;

use aes::Aes256;
use ctr::Ctr128BE;
use hmac::{
    digest::{generic_array::GenericArray, typenum::U32, Output},
    Hmac,
};
use sha2::Sha256;

pub use crate::{
    decrypt::Decryptor,
    encrypt::Encryptor,
    error::{Error, Result},
    params::Params,
};

#[cfg(feature = "alloc")]
pub use crate::{
    decrypt::decrypt,
    encrypt::{encrypt, encrypt_with_params},
};

/// A type alias for AES-256-CTR.
type Aes256Ctr128BE = Ctr128BE<Aes256>;

/// A type alias for HMAC-SHA-256.
type HmacSha256 = Hmac<Sha256>;

/// A type alias for output of HMAC-SHA-256.
type HmacSha256Output = Output<HmacSha256>;

/// A type alias for key of HMAC-SHA-256.
type HmacSha256Key = GenericArray<u8, U32>;