CI, readme and deps version bump
This commit is contained in:
parent
8ecb987f50
commit
6fbbc3f2d5
6 changed files with 301 additions and 36 deletions
80
.github/workflows/linux.yml
vendored
Normal file
80
.github/workflows/linux.yml
vendored
Normal file
|
@ -0,0 +1,80 @@
|
|||
name: CI (Linux)
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
|
||||
jobs:
|
||||
build_and_test:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
version:
|
||||
- stable
|
||||
- nightly
|
||||
|
||||
name: ${{ matrix.version }} - x86_64-unknown-linux-gnu
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: ⚡ Cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/registry
|
||||
~/.cargo/git
|
||||
target
|
||||
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
||||
|
||||
- name: Install ${{ matrix.version }}
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: ${{ matrix.version }}-x86_64-unknown-linux-gnu
|
||||
profile: minimal
|
||||
override: true
|
||||
|
||||
- name: check build
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: check
|
||||
args: --all --bins --examples --tests
|
||||
|
||||
- name: tests
|
||||
uses: actions-rs/cargo@v1
|
||||
timeout-minutes: 40
|
||||
with:
|
||||
command: test
|
||||
args: --all --all-features --no-fail-fast
|
||||
|
||||
- name: Generate coverage file
|
||||
if: matrix.version == 'stable' && (github.ref == 'refs/heads/master' || github.event_name == 'pull_request')
|
||||
uses: actions-rs/tarpaulin@v0.1
|
||||
with:
|
||||
version: '0.15.0'
|
||||
args: '-t 1200'
|
||||
|
||||
- name: Upload to Codecov
|
||||
if: matrix.version == 'stable' && (github.ref == 'refs/heads/master' || github.event_name == 'pull_request')
|
||||
uses: codecov/codecov-action@v1
|
||||
with:
|
||||
file: cobertura.xml
|
||||
|
||||
- name: generate documentation
|
||||
if: matrix.version == 'stable' && (github.repository == 'mcaptcha/mCaptcha')
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: doc
|
||||
args: --no-deps --workspace --all-features
|
||||
|
||||
- name: Deploy to GitHub Pages
|
||||
if: matrix.version == 'stable' && (github.repository == 'mcaptcha/mCaptcha')
|
||||
uses: JamesIves/github-pages-deploy-action@3.7.1
|
||||
with:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
BRANCH: gh-pages
|
||||
FOLDER: target/doc
|
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,3 +1,3 @@
|
|||
/target
|
||||
**/*.rs.bk
|
||||
Cargo.lock
|
||||
Cargo.locktarpaulin-report.html
|
||||
|
|
154
Cargo.lock
generated
Normal file
154
Cargo.lock
generated
Normal file
|
@ -0,0 +1,154 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "bincode"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d175dfa69e619905c4c3cdb7c3c203fa3bdd5d51184e3afdb2742c0280493772"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "cpuid-bool"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634"
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "opaque-debug"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
|
||||
|
||||
[[package]]
|
||||
name = "pow_sha256"
|
||||
version = "0.2.1"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"serde",
|
||||
"sha2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.123"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92d5161132722baa40d802cc70b15262b98258453e85e5d1d365c757c73869ae"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.123"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9391c295d64fc0abb2c556bad848f33cb8296276b1ad2677d1ae1ace4f258f31"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa827a14b29ab7f44778d14a88d3cb76e949c45083f7dbfa507d0cb699dc12de"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"cfg-if",
|
||||
"cpuid-bool",
|
||||
"digest",
|
||||
"opaque-debug",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.61"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed22b90a0e734a23a7610f4283ac9e5acfb96cbb30dfefa540d66f866f1c09c5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
|
|
@ -14,6 +14,6 @@ categories = ["algorithms", "cryptography::cryptocurrencies"]
|
|||
|
||||
|
||||
[dependencies]
|
||||
sha2 = "0.8.0"
|
||||
serde = { version = "1.0.97", features = ["derive"] }
|
||||
bincode = "1.1.4"
|
||||
sha2 = "0.9"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
bincode = "1.3"
|
||||
|
|
|
@ -1,19 +1,42 @@
|
|||
# PoW_SHA256
|
||||
|
||||
> Shuttlecraft'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.
|
||||
|
||||
<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.
|
||||
|
||||
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.
|
||||
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](https://github.com/bddap/pow) by bddap with some new additions. Primary of these being:
|
||||
This is a fork of the [`pow` library](https://github.com/bddap/pow) 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
|
||||
- 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, ...)
|
||||
- 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.
|
||||
Other small changes have also been included of various importance but
|
||||
mostly just stylistic/ease of use improvements.
|
||||
|
||||
# Examples
|
||||
|
||||
|
@ -38,7 +61,8 @@ assert!(pw.is_valid_proof(&phrase))
|
|||
Prove more difficult work. This time targeting a time.
|
||||
|
||||
```rust
|
||||
// Greater diffculty this time around. Takes around 100,000 hashes to find a nonce of the correct difficulty.
|
||||
// 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();
|
||||
|
@ -51,21 +75,26 @@ 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.
|
||||
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.
|
||||
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.
|
||||
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:
|
||||
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:
|
||||
|
||||
```rust
|
||||
fn get_difficulty(average: u128) -> u128 {
|
42
src/lib.rs
42
src/lib.rs
|
@ -1,7 +1,8 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
use sha2::{digest::FixedOutput, Digest, Sha256};
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sha2::{Digest, Sha256};
|
||||
|
||||
const SALT: &str = "79ziepia7vhjgviiwjhnend3ofjqocsi2winc4ptqhmkvcajihywxcizewvckg9h6gs4j83v9";
|
||||
|
||||
/// Proof of Work over concrete type T. T can be any type that implements serde::Serialize.
|
||||
|
@ -20,9 +21,7 @@ impl<T: Serialize> PoW<T> {
|
|||
///
|
||||
/// Returns bincode::Error if serialization fails.
|
||||
pub fn prove_work(t: &T, difficulty: u128) -> bincode::Result<PoW<T>> {
|
||||
bincode_cfg()
|
||||
.serialize(t)
|
||||
.map(|v| Self::prove_work_serialized(&v, difficulty))
|
||||
bincode::serialize(t).map(|v| Self::prove_work_serialized(&v, difficulty))
|
||||
}
|
||||
|
||||
/// Create Proof of Work on an already serialized item of type T.
|
||||
|
@ -47,9 +46,7 @@ impl<T: Serialize> PoW<T> {
|
|||
|
||||
/// Calculate the PoW score with the provided input T.
|
||||
pub fn calculate(&self, t: &T) -> bincode::Result<u128> {
|
||||
bincode_cfg()
|
||||
.serialize(t)
|
||||
.map(|v| self.calculate_serialized(&v))
|
||||
bincode::serialize(t).map(|v| self.calculate_serialized(&v))
|
||||
}
|
||||
|
||||
/// Calculate the PoW score of an already serialized T and self.
|
||||
|
@ -61,8 +58,14 @@ impl<T: Serialize> PoW<T> {
|
|||
/// Verifies that the PoW is indeed generated out of the phrase provided.
|
||||
pub fn is_valid_proof(&self, t: &T) -> bool {
|
||||
match self.calculate(t) {
|
||||
Ok(res) => return if self.result == res.to_string() {true} else {false},
|
||||
Err(_) => return false
|
||||
Ok(res) => {
|
||||
return if self.result == res.to_string() {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
Err(_) => return false,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -70,7 +73,7 @@ impl<T: Serialize> PoW<T> {
|
|||
pub fn is_sufficient_difficulty(&self, target_diff: u128) -> bool {
|
||||
match self.result.parse::<u128>() {
|
||||
Ok(res) => return res >= target_diff,
|
||||
Err(_) => return false
|
||||
Err(_) => return false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -79,7 +82,7 @@ fn score(prefix_sha: Sha256, nonce: u64) -> u128 {
|
|||
first_bytes_as_u128(
|
||||
prefix_sha
|
||||
.chain(&nonce.to_be_bytes()) // to_be_bytes() converts to network endian
|
||||
.fixed_result()
|
||||
.finalize()
|
||||
.as_slice(),
|
||||
)
|
||||
}
|
||||
|
@ -88,14 +91,13 @@ fn score(prefix_sha: Sha256, nonce: u64) -> u128 {
|
|||
///
|
||||
/// panics if inp.len() < 16
|
||||
fn first_bytes_as_u128(inp: &[u8]) -> u128 {
|
||||
bincode_cfg().deserialize(&inp).unwrap()
|
||||
bincode::deserialize(&inp).unwrap()
|
||||
}
|
||||
|
||||
fn bincode_cfg() -> bincode::Config {
|
||||
let mut cfg = bincode::config();
|
||||
cfg.big_endian();
|
||||
cfg
|
||||
}
|
||||
//fn bincode_cfg() -> bincode::Config {
|
||||
// let mut cfg = bincode::config();
|
||||
// cfg.big_endian();
|
||||
// cfg
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
|
@ -141,8 +143,8 @@ mod test {
|
|||
let target: u8 = 1;
|
||||
let pw = PoW::prove_work(&target, DIFFICULTY).unwrap();
|
||||
let message: (u8, PoW<u8>) = (target, pw);
|
||||
let message_ser = bincode_cfg().serialize(&message).unwrap();
|
||||
let recieved_message: (u8, PoW<u8>) = bincode_cfg().deserialize(&message_ser).unwrap();
|
||||
let message_ser = bincode::serialize(&message).unwrap();
|
||||
let recieved_message: (u8, PoW<u8>) = bincode::deserialize(&message_ser).unwrap();
|
||||
assert_eq!(recieved_message, message);
|
||||
assert!(message.1.is_sufficient_difficulty(DIFFICULTY));
|
||||
assert!(message.1.is_valid_proof(&target));
|
||||
|
|
Loading…
Reference in a new issue