examples, doc and readme update

This commit is contained in:
Aravinth Manivannan 2021-03-06 17:07:28 +05:30
parent 2a23e064e1
commit 0bfbce0185
Signed by: realaravinth
GPG key ID: AD9F0F08E855ED88
4 changed files with 111 additions and 49 deletions

View file

@ -1,16 +1,16 @@
[package]
name = "pow_sha256"
version = "0.1.0"
authors = ["Robert Kornacki <robk@syre.io>, Aravinth Manivannan <realaravinth@bastsense.net>"]
authors = [ "Aravinth Manivannan <realaravinth@bastsense.net>", "Robert Kornacki <robk@syre.io>"]
description = """
SHA256 PoW on any serializable datatype.
SHA256 PoW on any serializable datatype used in mCaptcha
"""
edition = "2018"
keywords = ["PoW", "sha256", "proof-of-work"]
readme = "readme.md"
keywords = ["mCaptcha", "PoW", "sha256", "proof-of-work"]
readme = "README.md"
license = "MIT OR Apache-2.0"
repository = "https://github.com/mcaptcha/pow_sha256"
categories = ["algorithms", "cryptography::cryptocurrencies"]
categories = ["captcha", "algorithms", "cryptography::cryptocurrencies"]
[dependencies]

View file

@ -1,9 +1,7 @@
<div align="center">
<h1>PoW_SHA256</h1>
<h1>PoW-SHA256</h1>
<p>
<strong>PoW_SHA256 - SHA256 based Proof-of-Work</strong>
<strong>PoW-SHA256 - SHA256 based Proof-of-Work</strong>
</p>
[![Documentation](https://img.shields.io/badge/docs-master-blue)](https://mcaptcha.github.io/pow_sha256/pow_sha256/index.html)
@ -26,36 +24,39 @@ crate can be used to prove work was done on a given serializable input.
The input merely needs to implement `serde::Deserialize` to be used.
This is a fork of the [`pow` library](https://github.com/bddap/pow) by
bddap with some new additions. Primary of these being:
[@robkorn](https://github.com/robkorn/pow_sha256)) with some new
additions. Primary of these being:
- PoW datatype now saves the calculation result to be used for checking
proof validity given input
- `is_valid_proof` method to do the above mentioned
- PoW datatype no longer saves `u128` values as these are unsupported by
popular serialization formats (CBOR, Msgpack, ...)
- `is_sufficient_difficulty` method to check difficulty with new changes
- PoW datatype now offers a constructor
- Salt is no longer hard coded into the library, users can provide
unique salts.
Other small changes have also been included of various importance but
mostly just stylistic/ease of use improvements.
# Examples
## Examples
Prove work was done, specifically targeting a phrase.
Prove work specifically targeting a phrase.
```rust
use pow_sha256::PoW;
// Very easy difficulty
let difficulty = u128::max_value() - u128::max_value() / 2;
use pow_sha256::{ConfigBuilder, PoW};
let phrase = b"Phrase to be used.".to_vec();
let pw = PoW::prove_work(&phrase, difficulty).unwrap();
fn main() {
let config = ConfigBuilder::default()
.salt("myrandomsaltisnotlongenoug".into())
.build()
.unwrap();
// Asserting that the result is of sufficient difficulty
assert!(pw.is_sufficient_difficulty(difficulty));
let phrase = "ironmansucks";
// Asserting that the PoW was generated from the provided phrase
assert!(pw.is_valid_proof(&phrase))
const DIFFICULTY: u128 = u128::MAX / 32;
let work = config.prove_work(&phrase, DIFFICULTY).unwrap();
assert!(config.calculate(&work, &phrase).unwrap() >= DIFFICULTY);
assert!(config.is_valid_proof(&work, &phrase));
assert!(config.is_sufficient_difficulty(&work, DIFFICULTY));
}
```
Prove more difficult work. This time targeting a time.
@ -63,22 +64,36 @@ Prove more difficult work. This time targeting a time.
```rust
// Greater difficulty this time around. Takes around 100,000 hashes
// to find a nonce of the correct difficulty.
let difficulty = u128::max_value() - u128::max_value() / 100_000;
let now: u64 = get_unix_time_seconds();
let pw = PoW::prove_work(&now, difficulty).unwrap();
assert!(pw.is_sufficient_difficulty(difficulty));
assert!(pw.is_valid_proof(&phrase))
use pow_sha256::{ConfigBuilder, PoW};
fn main() {
let config = ConfigBuilder::default()
.salt("myrandomsaltisnotlongenoug".into())
.build()
.unwrap();
let phrase = "ironmansucks";
const DIFFICULTY: u128 = u128::max_value() - u128::max_value() / 100_000;
let work = config.prove_work(&phrase, DIFFICULTY).unwrap();
assert!(config.calculate(&work, &phrase).unwrap() >= DIFFICULTY);
assert!(config.is_valid_proof(&work, &phrase));
assert!(config.is_sufficient_difficulty(&work, DIFFICULTY));
}
```
## Hashing Scheme
# Hashing Scheme
A randomly generated constant, `SALT`, is used as prefix to prevent PoW
reuse from other systems such as proof of work blockchains.
`SALT` is used as prefix to prevent PoW reuse from other systems such as
proof of work blockchains.
SHA256 is calculated over the concatenation of the:
- SALT
- Serialized Input `T`
- Nonce
@ -86,8 +101,7 @@ SHA256 is calculated over the concatenation of the:
The first 16 bytes of the resulting hash are interpreted as a 128 bit
unsigned integer and saved as the final result.
# Choosing a difficulty setting.
## Choosing a difficulty setting.
Depending on your use case, difficulty settings often are best set
dynamically a la bitcoin.
@ -104,7 +118,8 @@ fn get_difficulty(average: u128) -> u128 {
}
```
Conversely we can use the same equation to calculate the probable number of hashes required to satisfy a given difficulty:
Conversely we can use the same equation to calculate the probable number
of hashes required to satisfy a given difficulty:
```rust
fn est_average(difficulty: u128) -> u128 {

21
examples/simple.rs Normal file
View file

@ -0,0 +1,21 @@
/* The easiest way to use this crate is with the default configuration.
* See `Default` implementation for the default configuration.
*/
use pow_sha256::{ConfigBuilder, PoW};
fn main() {
let config = ConfigBuilder::default()
.salt("myrandomsaltisnotlongenoug".into())
.build()
.unwrap();
let phrase = "ironmansucks";
const DIFFICULTY: u128 = u128::MAX / 32;
let work = config.prove_work(&phrase, DIFFICULTY).unwrap();
assert!(config.calculate(&work, &phrase).unwrap() >= DIFFICULTY);
assert!(config.is_valid_proof(&work, &phrase));
assert!(config.is_sufficient_difficulty(&work, DIFFICULTY));
}

View file

@ -1,3 +1,26 @@
//! MCaptch's SHA256 based Proof of Work library
//!
//! # Example:
//! ```rust
//! use pow_sha256::{ConfigBuilder, PoW};
//!
//! fn main() {
//! let config = ConfigBuilder::default()
//! .salt("myrandomsaltisnotlongenoug".into())
//! .build()
//! .unwrap();
//!
//! let phrase = "ironmansucks";
//!
//! const DIFFICULTY: u128 = u128::MAX / 32;
//!
//! let work = config.prove_work(&phrase, DIFFICULTY).unwrap();
//! assert!(config.calculate(&work, &phrase).unwrap() >= DIFFICULTY);
//! assert!(config.is_valid_proof(&work, &phrase));
//! assert!(config.is_sufficient_difficulty(&work, DIFFICULTY));
//! }
//! ```
use std::marker::PhantomData;
use derive_builder::Builder;
@ -13,7 +36,10 @@ pub struct PoW<T> {
_spook: PhantomData<T>,
}
/// Proof of Work over concrete type T. T can be any type that implements serde::Serialize.
/// Configuration for generting proof of work
/// Please choose a long, unique value for salt
/// Resistance to dictionary/rainbow attacks depend on uniqueness
/// of the salt
#[derive(Serialize, Deserialize, Builder, PartialEq, Clone, Debug)]
pub struct Config {
pub salt: String,
@ -22,8 +48,8 @@ pub struct Config {
impl Config {
/// Create Proof of Work over item of type T.
///
/// Make sure difficulty is not too high. A 64 bit difficulty, for example, takes a long time
/// on a general purpose processor.
/// Make sure difficulty is not too high. A 64 bit difficulty,
/// for example, takes a long time on a general purpose processor.
/// Returns bincode::Error if serialization fails.
pub fn prove_work<T>(&self, t: &T, difficulty: u128) -> bincode::Result<PoW<T>>
where
@ -35,8 +61,8 @@ impl Config {
/// Create Proof of Work on an already serialized item of type T.
/// The input is assumed to be serialized using network byte order.
///
/// Make sure difficulty is not too high. A 64 bit difficulty, for example, takes a long time
/// on a general purpose processor.
/// Make sure difficulty is not too high. A 64 bit difficulty,
/// for example, takes a long time on a general purpose processor.
pub fn prove_work_serialized<T>(&self, prefix: &[u8], difficulty: u128) -> PoW<T>
where
T: Serialize,