pow_sha256/README.md

122 lines
3.8 KiB
Markdown
Raw Normal View History

2019-05-11 02:58:06 +05:30
2021-03-06 09:48:58 +05:30
<div align="center">
<h1>PoW_SHA256</h1>
<p>
<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)
![CI (Linux)](<https://github.com/mcaptcha/pow_sha256/workflows/CI%20(Linux)/badge.svg>)
[![dependency status](https://deps.rs/repo/github/mcaptcha/pow_sha256/status.svg)](https://deps.rs/repo/github/mcaptcha/pow_sha256)
<br />
[![codecov](https://codecov.io/gh/mcaptcha/pow_sha256/branch/master/graph/badge.svg)](https://codecov.io/gh/mcaptcha/pow_sha256)
</div>
> pow_sha256's copy of `pow_sha256` by
> [robkorn](https://github.com/robkorn/pow_sha256)
> which is a modified version of [`pow` library](https://github.com/bddap/pow).
> All copyrights belong to the original authors.
2020-09-02 11:52:31 +05:30
2019-07-23 00:59:16 +05:30
Rust crate which generates SHA256 Proofs of Work on serializable datatypes.
2021-03-06 09:48:58 +05:30
Whether for blockchain-related projects or Hashcash-like schemes, this
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.
2019-05-11 02:58:06 +05:30
2021-03-06 09:48:58 +05:30
This is a fork of the [`pow` library](https://github.com/bddap/pow) by
bddap with some new additions. Primary of these being:
2021-03-06 09:48:58 +05:30
- 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
2021-03-06 09:48:58 +05:30
- PoW datatype no longer saves `u128` values as these are unsupported by
popular serialization formats (CBOR, Msgpack, ...)
2019-07-25 00:11:28 +05:30
- `is_sufficient_difficulty` method to check difficulty with new changes
2021-03-06 09:48:58 +05:30
Other small changes have also been included of various importance but
mostly just stylistic/ease of use improvements.
# Examples
Prove work was done, specifically targeting a phrase.
2019-05-13 22:53:00 +05:30
```rust
2019-07-23 21:48:43 +05:30
use pow_sha256::PoW;
// Very easy difficulty
let difficulty = u128::max_value() - u128::max_value() / 2;
let phrase = b"Phrase to be used.".to_vec();
let pw = PoW::prove_work(&phrase, difficulty).unwrap();
// Asserting that the result is of sufficient difficulty
2019-07-24 20:54:39 +05:30
assert!(pw.is_sufficient_difficulty(difficulty));
// Asserting that the PoW was generated from the provided phrase
assert!(pw.is_valid_proof(&phrase))
```
Prove more difficult work. This time targeting a time.
2019-05-13 22:53:00 +05:30
```rust
2021-03-06 09:48:58 +05:30
// 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();
2019-07-25 00:11:28 +05:30
assert!(pw.is_sufficient_difficulty(difficulty));
assert!(pw.is_valid_proof(&phrase))
```
2019-07-23 00:59:16 +05:30
# Hashing Scheme
2021-03-06 09:48:58 +05:30
A randomly generated constant, `SALT`, is used as prefix to prevent PoW
reuse from other systems such as proof of work blockchains.
2019-07-23 00:59:16 +05:30
SHA256 is calculated over the concatenation of the:
- SALT
- Serialized Input `T`
- Nonce
2021-03-06 09:48:58 +05:30
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.
2021-03-06 09:48:58 +05:30
Depending on your use case, difficulty settings often are best set
dynamically a la bitcoin.
2021-03-06 09:48:58 +05:30
However if your use case requires manual setting then it is trivial to
set one yourself. One way to do so is to choose the average number of
hashes desired with a function like this:
2019-05-13 22:53:00 +05:30
```rust
fn get_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 we can use the same equation to calculate the probable number of hashes required to satisfy a given difficulty:
2019-05-13 22:53:00 +05:30
```rust
fn est_average(difficulty: u128) -> u128 {
let m = u128::max_value();
if difficulty == m {
return m;
}
m / (m - difficulty)
}
```
# License
2019-07-25 00:11:28 +05:30
This project is dual-licensed under `Apache License Version 2.0` or `MIT license`.