better docs

master
Avril 3 years ago
parent 38f2696270
commit 70abb4303a
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -1,7 +1,7 @@
[package]
name = "khash"
description = "Kana hashes"
version = "2.0.3"
version = "2.0.4"
authors = ["Avril <flanchan@cumallover.me>"]
edition = "2018"
license = "GPL-3.0-or-later"
@ -26,7 +26,7 @@ sha2 = "0.9"
malloc-array = {version = "1.4", optional=true}
libc = {version = "0.2", optional=true}
crc = {version = "1.8", optional=true}
hex-literal = "0.2"
hex-literal = "0.3"
getrandom = "0.1"
[build-dependencies]

@ -155,8 +155,8 @@ pub unsafe extern "C" fn khash_max_length(algo: u8, _input_sz: libc::size_t, max
{
no_unwind!{
let hash_sz = match ctx::Algorithm::from(algo) {
ctx::Algorithm::Crc32 => std::mem::size_of::<hash::Crc32Checksum>(),
ctx::Algorithm::Crc64 => std::mem::size_of::<hash::Crc64Checksum>(),
#[cfg(feature="crc")] ctx::Algorithm::Crc32 => std::mem::size_of::<hash::Crc32Checksum>(),
#[cfg(feature="crc")] ctx::Algorithm::Crc64 => std::mem::size_of::<hash::Crc64Checksum>(),
ctx::Algorithm::Sha256 => std::mem::size_of::<hash::Sha256Hash>(),
ctx::Algorithm::Sha256Truncated => std::mem::size_of::<hash::Sha256Truncated>(),
};

@ -1,4 +1,11 @@
//! Contains contexts used for algorithms
//! Contains contexts used for the digest algorithms.
//!
//! These contexts contain the digest name and the salt to be used with the digest.
//!
//! # Defaults
//! Both the digest name (`Algorithm`) and the `Context` itself implement `Default`.
//! The default algorithm is `SHA256Truncated`, and the default `Context` uses this algorithm along with the default salt (which is the library's hard-coded static salt.)
use crate::*;
use std::{
io::{
@ -7,14 +14,22 @@ use std::{
};
/// An algorithm to use for the context.
///
/// # CRC
/// `CRC32` and `CRC64` are only available if compiled with the default "crc" feature enabled.
/// If the library is compiled without this feature, but with the "ffi" feature (i.e. generates native libraries), then FFI requests for the CRC family of digests will instead use the default (`Sha256Truncated`).
#[derive(Clone,Debug,PartialEq,Eq,Hash)]
pub enum Algorithm
{
#[cfg(feature="crc")]
#[cfg(feature="crc")]
/// The 32 bit CRC checksum (requires default feature `crc`)
Crc32,
#[cfg(feature="crc")]
#[cfg(feature="crc")]
/// The 64 bit CRC checksum (requires default feature `crc`)
Crc64,
/// The SHA256 hash
Sha256,
/// The SHA256 hash truncated to the first 64 bits
Sha256Truncated,
}
@ -27,6 +42,9 @@ impl Default for Algorithm
}
/// A kana-hash context containing it's salt and algorithm.
///
/// # Default
/// The default context contains the `SHA256Truncated` digest algorithm and the library's hard-coded static salt.
#[derive(Clone,Debug,PartialEq,Eq,Hash)]
pub struct Context
{

@ -1,4 +1,4 @@
//! Error for kana-hash functions
//! Error for kana-hash operation
use std::{
fmt,
io,

@ -1,3 +1,36 @@
//! # khash - Kana mnemonic hashes
//!
//! This library pretty prints salted hashes of a veriaty of digests in kana.
//! Mnemonics can be generated from slices or from streams.
//!
//! It has a Rust API documented here, as well as C FFI bindings and a C header (see `include/`.)
//!
//! ## Digest
//! The digests available are:
//! * SHA256 truncated to the first 64 bits (8 bytes) (default digest)
//! * SHA256 full
//! * CRC64 (requires "crc" default feature enabled)
//! * CRC32 (requires "crc" default feature enabled)
//!
//! ### Salting
//! The salting options for the digests are:
//! * Hard-coded embedded 32 byte salt (default)
//! * Fixed compile time 32 byte salt
//! * Fixed runtime 32 byte salt
//! * Dynamically sized runtime salt
//! * No salt
//! The salt (if any) is fed into the digest directly after all the data.
//! (See `ctx` and `salt` modules).
//!
//! ## Generating kana mnemonics from arbitrary data
//! To use the mnemonic generation algorithm on any binary data instead of just hash outputs, the `Digest` iterator type is provided.
//! The `Digest` iterator can be created from any type implementing `std::io::Read` and produces a kana mnemonic reading from the stream until its end.
//! ```
//! # use khash::Digest;
//! let input = "Hello world!";
//! let mnemonic: String = Digest::new(&mut input.as_bytes()).collect(); // Read the bytes from the `input` string and collect the kana mnemonic into a `String`
//! ```
#![cfg_attr(nightly, feature(test))]
#![allow(dead_code)]
#![allow(unused_imports)]
@ -162,7 +195,10 @@ mod tests {
let input = "owowowoakpwodkapowkdapowkdpaokwpdoakwd";
let algos = [ctx::Algorithm::Crc32, ctx::Algorithm::Crc64, ctx::Algorithm::Sha256, ctx::Algorithm::Sha256Truncated];
let algos = [#[cfg(feature="crc")] ctx::Algorithm::Crc32,
#[cfg(feature="crc")] ctx::Algorithm::Crc64,
ctx::Algorithm::Sha256,
ctx::Algorithm::Sha256Truncated];
for i in 0..1000
{
let max_len = max_length(algos[i%algos.len()].clone(), 0);
@ -177,7 +213,8 @@ mod tests {
}
}
pub const BUFFER_SIZE: usize = 4096;
/// The size used for internal buffers
const BUFFER_SIZE: usize = 4096;
mod array;
mod reinterpret;
@ -217,7 +254,14 @@ fn compute<T: Read>(context: &ctx::Context, mut from: T) -> Result<(usize, Strin
Ok((read,output))
}
/// Generate kana hash from a slice.
/// Generate kana hash from a slice of bytes with this digest.
///
/// # Example
/// To generate a hash with the default digest from a string
/// ```
/// # use khash::generate;
/// generate(&Default::default(), "Hello world!").expect("Failed to generate hash string");
/// ```
pub fn generate<T: AsRef<[u8]>>(context: &ctx::Context, bytes: T) -> Result<String, error::Error>
{
let bytes = bytes.as_ref();
@ -230,7 +274,26 @@ pub fn generate<T: AsRef<[u8]>>(context: &ctx::Context, bytes: T) -> Result<Stri
}
}
/// Generate kana hash from a stream
/// Generate kana hash from a stream of bytes with this digest.
/// # Example
/// To generate a hash from a file with the default digest
/// ```
/// # use khash::generate_stream;
/// # use std::{path::Path, fs::OpenOptions};
/// fn hash_file(file_name: impl AsRef<Path>) -> String
/// {
/// let mut file = OpenOptions::new()
/// .read(true)
/// .open(file_name).expect("Failed to open file");
///
/// let file_size = file.metadata().expect("Failed to stat file").len();
///
/// let (bytes_read, hash) = generate_stream(&Default::default(), &mut file).expect("Failed to generate hash from file");
/// assert_eq!(bytes_read as u64, file_size, "Failed to read whole file");
///
/// hash
/// }
/// ```
#[inline] pub fn generate_stream<T: Read+?Sized>(context: &ctx::Context, from: &mut T) -> Result<(usize, String), error::Error>
{
compute(context, from)

@ -1,3 +1,20 @@
//! Salt for the digest `Context` (see module `ctx`)
//!
//! # Salt kinds
//! * Hard-coded embedded 32 byte salt (default)
//! * Fixed compile time or global static 32 byte salt
//! * Fixed runtime 32 byte salt
//! * Dynamically sized runtime salt
//! * No salt
//!
//! You can also generate a random salt at runtime with `Salt::random()` which uses `getrandom`'s RNG to create a fixed 32 bytes salt.
//!
//! # Method of salting
//! The salt is fed into the hashing function directly after the data.
//!
//! # FFI note
//! When generating a dynamic salt from an FFI context, there is a hard limit of 1024 bytes for safety reasons. This is more than enough data for a salt.
#[cfg(feature="ffi")] use malloc_array::*;
use getrandom::{
@ -14,19 +31,35 @@ use std::{
convert::{TryInto,TryFrom},
};
/// The static salt size
/// The static salt size. (32 bytes.)
///
/// When providing a compile-time or otherwise global salt, it must be of this size.
pub const SIZE: usize = 32;
/// The default static salt
/// The default embedded static salt.
///
/// It is recommended to use your own salt instead of this one, but this is used as the default if a salt option is not provided.
///
/// # Guarantee
/// This salt is guaranteed stay the same throughout all versions and iterations of this library.
/// It was randomly generated as the 32 bytes hex literal `hex!("6787f049791466d5a31a3aa6f7138d8fbb907fd1785758298b5c97b0f3fb31ff")`.
pub static EMBEDDED_SALT: &'static [u8; SIZE] = STATIC_SALT;
const STATIC_SALT: &[u8; SIZE] = &hex!("6787f049791466d5a31a3aa6f7138d8fbb907fd1785758298b5c97b0f3fb31ff");
/// A salt to use for the kana-hash algorithm
/// A salt to use for the kana-hash algorithm, or lack thereof.
///
/// It is recommended to provide your own salt, but the default `EMBEDDED_SALT` can be used instead.
#[derive(Clone,PartialEq,Eq,Hash,Debug)]
pub enum Salt
{
/// Do not salt the hash at all
None,
/// Salt with a compile-time, global, or leaked 32 byte array
Static(&'static [u8; SIZE]),
/// Salt with a runtime 32 byte array
Fixed([u8; SIZE]),
/// Salt with a runtime dynamic boxed byte slice of any size (must be at least 1)
Dynamic(Box<[u8]>),
}
@ -65,7 +98,7 @@ impl Salt
getrandom(&mut buffer[..])?;
Ok(Self::Fixed(buffer))
}
/// The default internal salt
/// The default embedded salt
pub const fn internal() -> Self
{
Self::Static(STATIC_SALT)

@ -1,6 +1,14 @@
use crate::*;
/// A streaming kana hash digest
/// A streaming kana hash digest.
///
/// This type can be used to generate kana mnemonics from any data.
/// It wraps a type implementing `std::io::Read` and produces a kana mnemonic reading from the stream until its end.
/// ```
/// # use khash::Digest;
/// let input = "Hello world!";
/// let mnemonic: String = Digest::new(&mut input.as_bytes()).collect(); // Read the bytes from the `input` string and collect the kana mnemonic into a `String`
/// ```
pub struct Digest<'a, T>
where T: Read
{
@ -9,7 +17,7 @@ where T: Read
impl<'a, T: Read> Digest<'a, T>
{
/// Create a new stream digest from the input
/// Create a new stream digest iterator from the input stream.
pub fn new(input: &'a mut T) -> Self
{
Self{input}
@ -18,7 +26,7 @@ impl<'a, T: Read> Digest<'a, T>
impl<'a, T: Read> Iterator for Digest<'a, T>
{
type Item = String;
type Item = String; //TODO: Change this to `char` and keep an internal buffer that we `fmt::write!` the mnemonic digest to instead of `format!`ing it.
fn next(&mut self) -> Option<Self::Item>
{
let mut buffer = [0u8; 2];

Loading…
Cancel
Save