|Avril 70abb4303a||6 months ago|
|cli||9 months ago|
|contrib/kana-hash||1 year ago|
|include||1 year ago|
|node||1 year ago|
|src||6 months ago|
|.gitignore||10 months ago|
|Cargo.toml||6 months ago|
|LICENSE||1 year ago|
|Makefile||8 months ago|
|README.org||1 year ago|
|build.rs||10 months ago|
|package-binaries||1 year ago|
Kana mnemonic hashes
uguu~ using the default salt.
The dynamic library is built with
Rust, and the CLI example program is built with
The default build configuration builds both the dynamic library, static library, and the CLI example program and copies them to
/usr/local/bin/kana-hash respectively. Also installed is the C header to
$ make && sudo make install
The install path can be changed by editing the
INSTALL-INCLUDE paths in the Makefile.
To remove installed binaries, run:
$ sudo make uninstall
The Makefile contains some other build directives.
libkhash builds the shared and static library with native architecture optimisations enabled.
If you are intending to move the libraries to another architecture, this might not be desireable.
To build without such optimisations, run:
$ make khash-nonative
To build and run all tests, run:
$ make test
make directive builds both the library and the CLI example program.
To build just the CLI example program, run:
$ cd cli && make
This library is written in Rust and has a Rust library target. See Rustdocs for details
A header file is provided for C programs wanting to use the khash interface.
Documented more fully in ./include/khash.h.
All symbols defined here begin with either
KHASH_ (for macros) or
To create a context
#include <khash.h> const char* input_salt = "salt!"; const char* input_data = "some data to hash". khash_context ctx; assert(khash_new_context(KHASH_ALGO_SHA256, KHASH_SALT_TYPE_SPECIFIC, input_salt, strlen(input_salt), &ctx) == KHASH_SUCCESS, "khash_new_context() failed.");
Find the buffer length we need and allocate a buffer.
size_t length; assert(khash_length(&ctx, input_data, strlen(input_data), &length) == KHASH_SUCCESS, "khash_length() failed.");
Create the buffer and hash, then print the result to
char* buffer = alloca(length+1); assert(khash_do(&ctx, input_data, strlen(input_data), buffer, length) == KHASH_SUCCESS, "khash_do() failed."); buffer[length+1] = 0; // Ensure we have a NUL terminator. setlocale(LC_ALL, ""); //Ensure we can print UTF-8. printf("Kana hash: %s\n", buffer);
Alternatively, we can allocate the max length needed instead of calculating it.
size_t length; assert(khash_max_length(KHASH_ALGO_SHA256, strlen(input_data), &length) == KHASH_SUCCESS, "khash_max_length() failed."); char* buffer = alloca(length+1); memset(buffer, 0, length+1); //Ensure NUL terminators.
All macros defined are for options.
They cannot be combied as flags.
KHASH_ALGO_ prefixed ones are for use as the algo parameter in the
KHASH_SALT_TYPE_ prefixed ones are for use as the salt_type parameter.
KHASH_ERROR_ prefixed ones each indicate an error code returned by all of the functions.
||The default algorithm used by the library (truncated SHA256)|
||CRC32 checksum algorithm|
||CRC64 checksum algorithm|
||SHA256 hash algorithm|
||SHA256 truncated to 64-bits|
||The default static salt used by the library|
||A provided salt, as the data and of the size parameter passed to
||A randomly generated salt|
||The code returned by all of the functions when the operation was successful|
||There was an IO error|
||The was a text formatting related error|
||There was a hash length mismatch|
||The random number generator failed|
||There was an unknown error or the stack attempted to unwind past the FFI boundary.|
There are 2 exported structs, although you will rarely need to access their members directly.
||A salt allocated into a context by
|salt_type||The type of the salt.|
|size||The size of the salt.|
|body||A pointer to the body of the salt. (The memory allocated here is not guaranteed to be of the provided size.)|
||A context for the
|algo||The algorithm for this context.|
|flags||Placeholder for potential flags added in the future. Currently unused.|
|salt||The allocated salt. You shouldn't directly mess with this field.|
All defined functions return either
KHASH_SUCCESS or one of the
KHASH_ERROR_ values above.
||algo, salt_type, data, size, output||Creates a new context for use with other
||ctx||Free a context allocated with
||src, dst||Clone a context allocated with
||ctx, data, size, length||Compute the length required to hold the output string for
||ctx, data, size, output, output_size||Compute the kana-hash of size bytes from data and store no more than output_size of the the result into the string pointed to by output. Each pointer is expected to be valid. This function frees the supplied ctx after the hash has been computed, and thus ctx is no longer valid afterwards.|
||algo, input_len, output_len||Calculate the max possible size for the given algorithm (expected to be one of the
NPM package in ./node
Follow the /flanchan/libkhash/src/branch/master/installation section first.
$ npm install --save /path/to/repo/node
const hash = require('kana-hash');
Create the context by specifying an algorithm identifier, and an optional salt.
If provided, the salt must be of type
const ctx = new hash.Kana(hash.Kana.ALGO_DEFAULT, new hash.Salt("optional salt~"));
once() function consumes the context and outputs a hash string.
const output = ctx.once("input string");
If you want to reuse the context, use the
const output = ctx.hash("input string");
The context must be release after use if you have not called
The new context must also be freed with either
const new_ctx = ctx.clone();
To create a hash in one line you can do one of the following.
const hash1 = new Kana(Kana.ALGO_DEFAULT, new Salt("salt~")).once("input string~"); //Allocates the exact space required for the output string. const hash2 = Kana.single(Kana.ALGO_DEFAULT, new Salt("salt~"), "input string~"); //Allocates the max space required for the output string, instead of the exact. Might be faster.
The 2 exported objects are
Kana's constructor expects between 0 and 2 arguments.
The first is either an algorithm definition or empty, if empty
Kana uses the default algorithm (truncated SHA256).
The second is either an instance of
Salt or empty, if empty
Kana uses the default library salt.
Salt's constructor expects 0 or 1 argument.
Either a string to use as the specific salt or empty, if empty there is no salt.
Kana also has a static function
||Algorithm definition||The default algorithm specified by the library (set to sha256 truncated)|
||Algorithm definition||CRC32 checksum algorithm|
||Algorithm definition||CRC64 checksum algorithm|
||Algorithm definition||SHA256 hashing algorithm|
||Algorithm definition||Truncated SHA256 algorithm, to 64-bits|
||Salt||A cryptographically secure random salt|
||Salt||The library's default static salt|
The strings generated by this library are meant to be pretty, not secure. It is not a secure way of representing a hash as many collisions are possible.
The kana algorithm is a 16-bit block digest that works as follows:
The most and least significant 8 bits are each seperated into Stage 0 and Stage 1 each operating on the first and second byte respectively.
The byte is sign tested (bitwise
0x80), store this as a boolean in sign0 (Negative becomes
1, positive becomes
The valid first character range is looked up using the result of the sign test (either 0 or 1), store the range in range, and the slice
KANA taken from the range in kana.
The first index is calculated as the unsigned first byte modulo the size (exclusive) of range. Store this as index.
Compute the value of the first byte bitwise
XOR the second byte, store this as index1.
The swap table is checked to see if index + start of range has an entry. Then each following step is checked in order:
If the swap entry exists and index1 bitwise
0, set the first character of the output to the value found in the swap table.
If the swap entry exists and index1 bitwise
0 and index + start of range has an entry in the 2nd swap table, set the first character of the output to the value found in the 2nd swap table.
In any other case, set the first character of the output to the value found in the kana slice at index.
Compute a sub table for index plus the start of range using the ranges defined in
KANA_SUB_VALID_FOR and store it in sub. If there is no sub table possible, skip to step 3.
If there is an entry in sub for the index of the 2nd byte modulo the size of
KANA_SUB, set the second output character to be that character.
If there was no value set from the sub table, the 2nd output character becomes the first output character from inputting the 2nd byte back through Stage 0 as the first byte.
Concatenate both characters and move to the next 16-bit block.
It is valid for a single iterator to produce between 0 and 2 characters but no more.
If an input given to the algorithm that cannot be divided exactly into 16-bit blocks (i.e. one byte is left over), a padding byte of 0 is added as the 2nd byte to make it fit.
GPL'd with love <3