Docs
This commit is contained in:
parent
8b045cf61c
commit
69e75e116c
3 changed files with 77 additions and 6 deletions
|
@ -1,11 +1,14 @@
|
||||||
[package]
|
[package]
|
||||||
name = "pow"
|
name = "pow"
|
||||||
version = "0.1.0"
|
version = "0.1.1"
|
||||||
authors = ["Andrew Dirksen <andrew@dirksen.com>"]
|
authors = ["Andrew Dirksen <andrew@dirksen.com>"]
|
||||||
description = """
|
description = """
|
||||||
Tag arbitrary data types with proof of work based on sha256.
|
Generate or verify sha256 based proofs of work over arbitrary typed data.
|
||||||
"""
|
"""
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
documentation = "https://docs.rs/pow"
|
||||||
|
tags = ["proof of work", "pw set", "powtag", "tag"]
|
||||||
|
readme = "readme.md"
|
||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|
5
readme.md
Normal file
5
readme.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
# Pow
|
||||||
|
|
||||||
|
Typed proof of work tags.
|
||||||
|
|
||||||
|
[docs](https://docs.rs/pow)
|
71
src/lib.rs
71
src/lib.rs
|
@ -8,7 +8,10 @@
|
||||||
//!
|
//!
|
||||||
//! ```
|
//! ```
|
||||||
//! use pow::Pow;
|
//! use pow::Pow;
|
||||||
//! let difficulty = u128::max_value() / 2; // very easy mode
|
//!
|
||||||
|
//! // very easy mode
|
||||||
|
//! let difficulty = u128::max_value() - u128::max_value() / 2;
|
||||||
|
//!
|
||||||
//! let phrase = b"Phrase to tag.".to_vec();
|
//! let phrase = b"Phrase to tag.".to_vec();
|
||||||
//! let pw = Pow::prove_work(&phrase, difficulty).unwrap();
|
//! let pw = Pow::prove_work(&phrase, difficulty).unwrap();
|
||||||
//! assert!(pw.score(&phrase).unwrap() >= difficulty);
|
//! assert!(pw.score(&phrase).unwrap() >= difficulty);
|
||||||
|
@ -22,14 +25,74 @@
|
||||||
//! # SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs()
|
//! # SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs()
|
||||||
//! # }
|
//! # }
|
||||||
//! # use pow::Pow;
|
//! # use pow::Pow;
|
||||||
//! let difficulty = u128::max_value() / 10_000 * 9_999; // more diffcult, around 10_000 hashes
|
//!
|
||||||
|
//! // more diffcult, takes around 100_000 hashes to generate proof
|
||||||
|
//! let difficulty = u128::max_value() - u128::max_value() / 100_000;
|
||||||
|
//!
|
||||||
//! let now: u64 = get_unix_time_seconds();
|
//! let now: u64 = get_unix_time_seconds();
|
||||||
//! let pw = Pow::prove_work(&now, difficulty).unwrap();
|
//! let pw = Pow::prove_work(&now, difficulty).unwrap();
|
||||||
//! assert!(pw.score(&now).unwrap() >= difficulty);
|
//! assert!(pw.score(&now).unwrap() >= difficulty);
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
//! Expected computional cost scales something like
|
//! # Score scheme
|
||||||
//! O(u128::max_value() / (u128::max_value() - difficulty))
|
//!
|
||||||
|
//! To score a proof of work for a given (target, Pow) pair:
|
||||||
|
//! Sha256 is calculated over the concatenation SALT + target + Pow.
|
||||||
|
//! The first 16 bytes of the hash are interpreted as a 128 bit unsigned integer.
|
||||||
|
//! That integer is the score.
|
||||||
|
//! A constant, SALT, is used as prefix to prevent pow reuse from other systems such as proof
|
||||||
|
//! of work blockchains.
|
||||||
|
//!
|
||||||
|
//! In other words:
|
||||||
|
//!
|
||||||
|
//! ```
|
||||||
|
//! # use serde::Serialize;
|
||||||
|
//! # use pow::Pow;
|
||||||
|
//! # use core::any::Any;
|
||||||
|
//! # const SALT: &'static str = "not the actual salt used";
|
||||||
|
//! # fn serialize<T: Serialize>(_: &T) -> u8 { 0 } // not the actual serialize function
|
||||||
|
//! # fn deserialize(_: &[u8]) -> u128 { 0 } // not the actual deserialize function
|
||||||
|
//! # fn sha256(_: &u8) -> [u8; 32] { [0; 32] } // not the actual sha256 function
|
||||||
|
//! fn score<T: Serialize>(target: &T, pow_tag: &Pow<T>) -> u128 {
|
||||||
|
//! let bytes = serialize(&SALT) + serialize(target) + serialize(pow_tag);
|
||||||
|
//! let hash = sha256(&bytes);
|
||||||
|
//! deserialize(&hash[..16])
|
||||||
|
//! }
|
||||||
|
//! ```
|
||||||
|
//!
|
||||||
|
//! # Serialization encoding.
|
||||||
|
//!
|
||||||
|
//! It shouldn't matter to users of this library, but the bincode crate is used for cheap
|
||||||
|
//! derterministic serialization. All values are serialized using network byte order.
|
||||||
|
//!
|
||||||
|
//! # Threshold scheme
|
||||||
|
//!
|
||||||
|
//! Given a minimum score m. A Pow p satisfies the minimum score for target t iff score(t, p) >= m.
|
||||||
|
//!
|
||||||
|
//! # Choosing a difficulty setting.
|
||||||
|
//!
|
||||||
|
//! Difficulty settings are usually best adjusted dynamically a la bitcoin.
|
||||||
|
//!
|
||||||
|
//! To manually select a difficulty, choose the average number of hashes required.
|
||||||
|
//!
|
||||||
|
//! ```
|
||||||
|
//! fn difficulty(average: u128) -> u128 {
|
||||||
|
//! debug_assert_ne!(average, 0, "It is impossible to prove work in zero attempts.");
|
||||||
|
//! let m = u128::max_value();
|
||||||
|
//! m - m / average
|
||||||
|
//! }
|
||||||
|
//! ```
|
||||||
|
//!
|
||||||
|
//! Conversely, to calculate probable number of hashes required to satisfy a given minimum
|
||||||
|
//! difficulty.
|
||||||
|
//!
|
||||||
|
//! fn average(difficulty: u128) -> u128 {
|
||||||
|
//! let m = u128::max_value();
|
||||||
|
//! if difficulty == m {
|
||||||
|
//! return m;
|
||||||
|
//! }
|
||||||
|
//! m / (m - difficulty)
|
||||||
|
//! }
|
||||||
|
|
||||||
mod proof_of_work;
|
mod proof_of_work;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue