Add a bunch of documentation and examples.
This commit is contained in:
@@ -45,8 +45,8 @@ pub mod ssh;
|
|||||||
/// used by TLS and others.
|
/// used by TLS and others.
|
||||||
pub mod x509;
|
pub mod x509;
|
||||||
/// An implementation of the SHA family of hashes, including the relatively
|
/// An implementation of the SHA family of hashes, including the relatively
|
||||||
/// weak SHA1 and a bunch of hashes you should use, like SHA2-256, SHA2-384,
|
/// weak SHA1 and a bunch of hashes you should use, like the SHA2 and SHA3
|
||||||
/// and SHA2-512.
|
/// hashes.
|
||||||
pub mod sha;
|
pub mod sha;
|
||||||
|
|
||||||
/// A generic trait for defining what a key pair looks like. This is useful
|
/// A generic trait for defining what a key pair looks like. This is useful
|
||||||
|
|||||||
@@ -1,6 +1,63 @@
|
|||||||
|
//! The SHA family of hash functions, as defined by NIST; specifically, from
|
||||||
|
//! NIST 180-4 (for SHA1 and SHA2) and NIST 202 (for SHA3).
|
||||||
|
//!
|
||||||
|
//! These hash functions are used through their instantiation of the `Hash`
|
||||||
|
//! trait, located in the parent `simple_crypto` module and re-exported
|
||||||
|
//! here for convenience. Thus, you're not going to see a lot of functions
|
||||||
|
//! or macros, here, just the type declarations.
|
||||||
|
//!
|
||||||
|
//! To use SHA2-384, as an example, you could run the following code:
|
||||||
|
//!
|
||||||
|
//! ```rust
|
||||||
|
//! use simple_crypto::sha::{Hash,SHA384};
|
||||||
|
//!
|
||||||
|
//! let empty: [u8; 0] = [0; 0];
|
||||||
|
//! let mut digest_incremental = SHA384::new();
|
||||||
|
//! digest_incremental.update(&empty);
|
||||||
|
//! digest_incremental.update(&empty);
|
||||||
|
//! digest_incremental.update(&empty);
|
||||||
|
//! let result = digest_incremental.finalize();
|
||||||
|
//!
|
||||||
|
//! assert_eq!(result, vec![0x38,0xb0,0x60,0xa7,0x51,0xac,0x96,0x38,
|
||||||
|
//! 0x4c,0xd9,0x32,0x7e,0xb1,0xb1,0xe3,0x6a,
|
||||||
|
//! 0x21,0xfd,0xb7,0x11,0x14,0xbe,0x07,0x43,
|
||||||
|
//! 0x4c,0x0c,0xc7,0xbf,0x63,0xf6,0xe1,0xda,
|
||||||
|
//! 0x27,0x4e,0xde,0xbf,0xe7,0x6f,0x65,0xfb,
|
||||||
|
//! 0xd5,0x1a,0xd2,0xf1,0x48,0x98,0xb9,0x5b]);
|
||||||
|
//! ```
|
||||||
|
//!
|
||||||
|
//! For other hashes, just substitute the appropriate hash structure for
|
||||||
|
//! `SHA384`. The `Hash` trait also includes a do-it-all-at-once built-in
|
||||||
|
//! function for those cases when you just have a single blob of data
|
||||||
|
//! you want to hash, rather than an incremental set of data:
|
||||||
|
//!
|
||||||
|
//! ```rust
|
||||||
|
//! use simple_crypto::sha::{Hash,SHA3_256};
|
||||||
|
//!
|
||||||
|
//! let empty: [u8; 0] = [0; 0];
|
||||||
|
//! let result = SHA3_256::hash(&empty);
|
||||||
|
//!
|
||||||
|
//! assert_eq!(result, vec![0xa7,0xff,0xc6,0xf8,0xbf,0x1e,0xd7,0x66,
|
||||||
|
//! 0x51,0xc1,0x47,0x56,0xa0,0x61,0xd6,0x62,
|
||||||
|
//! 0xf5,0x80,0xff,0x4d,0xe4,0x3b,0x49,0xfa,
|
||||||
|
//! 0x82,0xd8,0x0a,0x4b,0x80,0xf8,0x43,0x4a]);
|
||||||
|
//! ```
|
||||||
|
//!
|
||||||
|
//! In general, you should not use SHA1 for anything but supporting legacy
|
||||||
|
//! systems. We recommend either SHA2 or SHA3 at their 256-, 384-, or 512-bit
|
||||||
|
//! sizes. NIST claims (in FIPS 202, page 23-24) that SHA2 and SHA3 are
|
||||||
|
//! approximately equivalent in terms of security for collision, preimate,
|
||||||
|
//! and second preimage attacks, but that SHA3 improves upon SHA2 against
|
||||||
|
//! length-extension and other attacks. On the other hand, SHA2 has been
|
||||||
|
//! banged on for a little longer, and there's some claims that it's more
|
||||||
|
//! resistant to quantum attacks. So ... make your own decisions.
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod shared;
|
mod shared;
|
||||||
|
mod sha1;
|
||||||
|
mod sha2;
|
||||||
|
mod sha3;
|
||||||
|
|
||||||
pub mod sha1;
|
pub use super::Hash;
|
||||||
pub mod sha2;
|
pub use self::sha1::SHA1;
|
||||||
pub mod sha3;
|
pub use self::sha2::{SHA224,SHA256,SHA384,SHA512};
|
||||||
|
pub use self::sha3::{SHA3_224,SHA3_256,SHA3_384,SHA3_512};
|
||||||
@@ -2,6 +2,25 @@ use byteorder::{BigEndian,WriteBytesExt};
|
|||||||
use super::super::Hash;
|
use super::super::Hash;
|
||||||
use sha::shared::calculate_k;
|
use sha::shared::calculate_k;
|
||||||
|
|
||||||
|
/// The SHA1 hash. Don't use this except to support legacy systems.
|
||||||
|
///
|
||||||
|
/// To use, you can run it in incremental mode -- by calling new(),
|
||||||
|
/// update() zero or more times, and then finalize() -- or you can
|
||||||
|
/// just invoke the hash directly. For example:
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use simple_crypto::sha::{Hash,SHA1};
|
||||||
|
///
|
||||||
|
/// let empty = [0; 0];
|
||||||
|
/// // Do the hash using the incremental API
|
||||||
|
/// let mut hashf = SHA1::new();
|
||||||
|
/// hashf.update(&empty);
|
||||||
|
/// let result_incremental = hashf.finalize();
|
||||||
|
/// // Do the hash using the direct API
|
||||||
|
/// let result_direct = SHA1::hash(&empty);
|
||||||
|
/// // ... and they should be the same
|
||||||
|
/// assert_eq!(result_incremental,result_direct);
|
||||||
|
/// ```
|
||||||
pub struct SHA1 {
|
pub struct SHA1 {
|
||||||
state: [u32; 5],
|
state: [u32; 5],
|
||||||
buffer: Vec<u8>,
|
buffer: Vec<u8>,
|
||||||
|
|||||||
@@ -2,6 +2,25 @@ use byteorder::{BigEndian,ByteOrder,WriteBytesExt};
|
|||||||
use sha::shared::calculate_k;
|
use sha::shared::calculate_k;
|
||||||
use super::super::Hash;
|
use super::super::Hash;
|
||||||
|
|
||||||
|
/// The SHA2-224 hash.
|
||||||
|
///
|
||||||
|
/// To use, you can run it in incremental mode -- by calling new(),
|
||||||
|
/// update() zero or more times, and then finalize() -- or you can
|
||||||
|
/// just invoke the hash directly. For example:
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use simple_crypto::sha::{Hash,SHA224};
|
||||||
|
///
|
||||||
|
/// let empty = [0; 0];
|
||||||
|
/// // Do the hash using the incremental API
|
||||||
|
/// let mut hashf = SHA224::new();
|
||||||
|
/// hashf.update(&empty);
|
||||||
|
/// let result_incremental = hashf.finalize();
|
||||||
|
/// // Do the hash using the direct API
|
||||||
|
/// let result_direct = SHA224::hash(&empty);
|
||||||
|
/// // ... and they should be the same
|
||||||
|
/// assert_eq!(result_incremental,result_direct);
|
||||||
|
/// ```
|
||||||
pub struct SHA224 {
|
pub struct SHA224 {
|
||||||
state: SHA256State
|
state: SHA256State
|
||||||
}
|
}
|
||||||
@@ -37,6 +56,25 @@ impl Hash for SHA224 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The SHA2-256 hash. [GOOD]
|
||||||
|
///
|
||||||
|
/// To use, you can run it in incremental mode -- by calling new(),
|
||||||
|
/// update() zero or more times, and then finalize() -- or you can
|
||||||
|
/// just invoke the hash directly. For example:
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use simple_crypto::sha::{Hash,SHA256};
|
||||||
|
///
|
||||||
|
/// let empty = [0; 0];
|
||||||
|
/// // Do the hash using the incremental API
|
||||||
|
/// let mut hashf = SHA256::new();
|
||||||
|
/// hashf.update(&empty);
|
||||||
|
/// let result_incremental = hashf.finalize();
|
||||||
|
/// // Do the hash using the direct API
|
||||||
|
/// let result_direct = SHA256::hash(&empty);
|
||||||
|
/// // ... and they should be the same
|
||||||
|
/// assert_eq!(result_incremental,result_direct);
|
||||||
|
/// ```
|
||||||
pub struct SHA256 {
|
pub struct SHA256 {
|
||||||
state: SHA256State
|
state: SHA256State
|
||||||
}
|
}
|
||||||
@@ -73,6 +111,25 @@ impl Hash for SHA256 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The SHA2-384 hash. [BETTER]
|
||||||
|
///
|
||||||
|
/// To use, you can run it in incremental mode -- by calling new(),
|
||||||
|
/// update() zero or more times, and then finalize() -- or you can
|
||||||
|
/// just invoke the hash directly. For example:
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use simple_crypto::sha::{Hash,SHA384};
|
||||||
|
///
|
||||||
|
/// let empty = [0; 0];
|
||||||
|
/// // Do the hash using the incremental API
|
||||||
|
/// let mut hashf = SHA384::new();
|
||||||
|
/// hashf.update(&empty);
|
||||||
|
/// let result_incremental = hashf.finalize();
|
||||||
|
/// // Do the hash using the direct API
|
||||||
|
/// let result_direct = SHA384::hash(&empty);
|
||||||
|
/// // ... and they should be the same
|
||||||
|
/// assert_eq!(result_incremental,result_direct);
|
||||||
|
/// ```
|
||||||
pub struct SHA384 {
|
pub struct SHA384 {
|
||||||
state: SHA512State
|
state: SHA512State
|
||||||
}
|
}
|
||||||
@@ -109,6 +166,25 @@ impl Hash for SHA384 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The SHA2-512 hash. [BEST]
|
||||||
|
///
|
||||||
|
/// To use, you can run it in incremental mode -- by calling new(),
|
||||||
|
/// update() zero or more times, and then finalize() -- or you can
|
||||||
|
/// just invoke the hash directly. For example:
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use simple_crypto::sha::{Hash,SHA512};
|
||||||
|
///
|
||||||
|
/// let empty = [0; 0];
|
||||||
|
/// // Do the hash using the incremental API
|
||||||
|
/// let mut hashf = SHA512::new();
|
||||||
|
/// hashf.update(&empty);
|
||||||
|
/// let result_incremental = hashf.finalize();
|
||||||
|
/// // Do the hash using the direct API
|
||||||
|
/// let result_direct = SHA512::hash(&empty);
|
||||||
|
/// // ... and they should be the same
|
||||||
|
/// assert_eq!(result_incremental,result_direct);
|
||||||
|
/// ```
|
||||||
pub struct SHA512 {
|
pub struct SHA512 {
|
||||||
state: SHA512State
|
state: SHA512State
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -225,7 +225,26 @@ impl Keccak {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SHA3_224 {
|
/// The SHA3-224 hash.
|
||||||
|
///
|
||||||
|
/// To use, you can run it in incremental mode -- by calling new(),
|
||||||
|
/// update() zero or more times, and then finalize() -- or you can
|
||||||
|
/// just invoke the hash directly. For example:
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use simple_crypto::sha::{Hash,SHA3_224};
|
||||||
|
///
|
||||||
|
/// let empty = [0; 0];
|
||||||
|
/// // Do the hash using the incremental API
|
||||||
|
/// let mut hashf = SHA3_224::new();
|
||||||
|
/// hashf.update(&empty);
|
||||||
|
/// let result_incremental = hashf.finalize();
|
||||||
|
/// // Do the hash using the direct API
|
||||||
|
/// let result_direct = SHA3_224::hash(&empty);
|
||||||
|
/// // ... and they should be the same
|
||||||
|
/// assert_eq!(result_incremental,result_direct);
|
||||||
|
/// ```
|
||||||
|
pub struct SHA3_224 {
|
||||||
state: Keccak
|
state: Keccak
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -292,6 +311,25 @@ mod sha224 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The SHA3-256 hash. [GOOD]
|
||||||
|
///
|
||||||
|
/// To use, you can run it in incremental mode -- by calling new(),
|
||||||
|
/// update() zero or more times, and then finalize() -- or you can
|
||||||
|
/// just invoke the hash directly. For example:
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use simple_crypto::sha::{Hash,SHA3_256};
|
||||||
|
///
|
||||||
|
/// let empty = [0; 0];
|
||||||
|
/// // Do the hash using the incremental API
|
||||||
|
/// let mut hashf = SHA3_256::new();
|
||||||
|
/// hashf.update(&empty);
|
||||||
|
/// let result_incremental = hashf.finalize();
|
||||||
|
/// // Do the hash using the direct API
|
||||||
|
/// let result_direct = SHA3_256::hash(&empty);
|
||||||
|
/// // ... and they should be the same
|
||||||
|
/// assert_eq!(result_incremental,result_direct);
|
||||||
|
/// ```
|
||||||
pub struct SHA3_256 {
|
pub struct SHA3_256 {
|
||||||
state: Keccak
|
state: Keccak
|
||||||
}
|
}
|
||||||
@@ -360,6 +398,25 @@ mod sha256 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The SHA3-384 hash. [BETTER]
|
||||||
|
///
|
||||||
|
/// To use, you can run it in incremental mode -- by calling new(),
|
||||||
|
/// update() zero or more times, and then finalize() -- or you can
|
||||||
|
/// just invoke the hash directly. For example:
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use simple_crypto::sha::{Hash,SHA3_384};
|
||||||
|
///
|
||||||
|
/// let empty = [0; 0];
|
||||||
|
/// // Do the hash using the incremental API
|
||||||
|
/// let mut hashf = SHA3_384::new();
|
||||||
|
/// hashf.update(&empty);
|
||||||
|
/// let result_incremental = hashf.finalize();
|
||||||
|
/// // Do the hash using the direct API
|
||||||
|
/// let result_direct = SHA3_384::hash(&empty);
|
||||||
|
/// // ... and they should be the same
|
||||||
|
/// assert_eq!(result_incremental,result_direct);
|
||||||
|
/// ```
|
||||||
pub struct SHA3_384 {
|
pub struct SHA3_384 {
|
||||||
state: Keccak
|
state: Keccak
|
||||||
}
|
}
|
||||||
@@ -432,6 +489,25 @@ mod sha384 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The SHA3-512 hash. [BEST]
|
||||||
|
///
|
||||||
|
/// To use, you can run it in incremental mode -- by calling new(),
|
||||||
|
/// update() zero or more times, and then finalize() -- or you can
|
||||||
|
/// just invoke the hash directly. For example:
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use simple_crypto::sha::{Hash,SHA3_512};
|
||||||
|
///
|
||||||
|
/// let empty = [0; 0];
|
||||||
|
/// // Do the hash using the incremental API
|
||||||
|
/// let mut hashf = SHA3_512::new();
|
||||||
|
/// hashf.update(&empty);
|
||||||
|
/// let result_incremental = hashf.finalize();
|
||||||
|
/// // Do the hash using the direct API
|
||||||
|
/// let result_direct = SHA3_512::hash(&empty);
|
||||||
|
/// // ... and they should be the same
|
||||||
|
/// assert_eq!(result_incremental,result_direct);
|
||||||
|
/// ```
|
||||||
pub struct SHA3_512 {
|
pub struct SHA3_512 {
|
||||||
state: Keccak
|
state: Keccak
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user