Skip to content
forked from bddap/pow

SHA256 PoW on any serializable datatype.

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT
Notifications You must be signed in to change notification settings

robkorn/pow_sha256

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

30 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PoW_SHA256

Rust crate which generates SHA256 Proofs of Work on serializable datatypes.

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.

This is a fork of the pow library by bddap 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

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.

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
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.

// Greater diffculty 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))

Hashing Scheme

A randomly generated constant, 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

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.

Depending on your use case, difficulty settings often are best set dynamically a la bitcoin.

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:

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:

fn est_average(difficulty: u128) -> u128 {
    let m = u128::max_value();
    if difficulty == m {
        return m;
    } 
    m / (m - difficulty)
}

License

This project is dual-licensed under Apache License Version 2.0 or MIT license.

About

SHA256 PoW on any serializable datatype.

Topics

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Rust 100.0%