u32 difficulty factor
This commit is contained in:
parent
e5b4baab3f
commit
d1473ae5aa
8 changed files with 38 additions and 19 deletions
8
CHANGELOG.md
Normal file
8
CHANGELOG.md
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
# Changelog
|
||||||
|
|
||||||
|
## 0.1
|
||||||
|
- PoW constructor
|
||||||
|
- unique salt
|
||||||
|
|
||||||
|
## 0.2
|
||||||
|
- Difficulty factor is now an unsigned 32 bit number
|
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -138,7 +138,7 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pow_sha256"
|
name = "pow_sha256"
|
||||||
version = "0.1.0"
|
version = "0.1.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode",
|
"bincode",
|
||||||
"derive_builder",
|
"derive_builder",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "pow_sha256"
|
name = "pow_sha256"
|
||||||
version = "0.1.0"
|
version = "0.1.1"
|
||||||
authors = [ "Aravinth Manivannan <realaravinth@bastsense.net>", "Robert Kornacki <robk@syre.io>"]
|
authors = [ "Aravinth Manivannan <realaravinth@bastsense.net>", "Robert Kornacki <robk@syre.io>"]
|
||||||
description = """
|
description = """
|
||||||
SHA256 PoW on any serializable datatype used in mCaptcha
|
SHA256 PoW on any serializable datatype used in mCaptcha
|
||||||
|
|
12
README.md
12
README.md
|
@ -27,7 +27,7 @@ This is a fork of the [`pow` library](https://github.com/bddap/pow) by
|
||||||
[@robkorn](https://github.com/robkorn/pow_sha256)) with some new
|
[@robkorn](https://github.com/robkorn/pow_sha256)) with some new
|
||||||
additions. Primary of these being:
|
additions. Primary of these being:
|
||||||
|
|
||||||
- PoW datatype now offers a constructor
|
- PoW datatype now offers a constructor
|
||||||
- Salt is no longer hard coded into the library, users can provide
|
- Salt is no longer hard coded into the library, users can provide
|
||||||
unique salts.
|
unique salts.
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ fn main() {
|
||||||
|
|
||||||
let phrase = "ironmansucks";
|
let phrase = "ironmansucks";
|
||||||
|
|
||||||
const DIFFICULTY: u128 = u128::MAX / 32;
|
const DIFFICULTY: u32 = 1000;
|
||||||
|
|
||||||
let work = config.prove_work(&phrase, DIFFICULTY).unwrap();
|
let work = config.prove_work(&phrase, DIFFICULTY).unwrap();
|
||||||
assert!(config.calculate(&work, &phrase).unwrap() >= DIFFICULTY);
|
assert!(config.calculate(&work, &phrase).unwrap() >= DIFFICULTY);
|
||||||
|
@ -76,7 +76,7 @@ fn main() {
|
||||||
|
|
||||||
let phrase = "ironmansucks";
|
let phrase = "ironmansucks";
|
||||||
|
|
||||||
const DIFFICULTY: u128 = u128::max_value() - u128::max_value() / 100_000;
|
const DIFFICULTY: u32 = 100_000;
|
||||||
|
|
||||||
let work = config.prove_work(&phrase, DIFFICULTY).unwrap();
|
let work = config.prove_work(&phrase, DIFFICULTY).unwrap();
|
||||||
|
|
||||||
|
@ -131,6 +131,10 @@ fn est_average(difficulty: u128) -> u128 {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
# License
|
## Changelog
|
||||||
|
|
||||||
|
See [CHANGELOG.md](./CHANGELOG.md)
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
This project is dual-licensed under `Apache License Version 2.0` or `MIT license`.
|
This project is dual-licensed under `Apache License Version 2.0` or `MIT license`.
|
||||||
|
|
|
@ -12,10 +12,9 @@ fn main() {
|
||||||
|
|
||||||
let phrase = "ironmansucks";
|
let phrase = "ironmansucks";
|
||||||
|
|
||||||
const DIFFICULTY: u128 = u128::MAX / 32;
|
const DIFFICULTY: u32 = 1000;
|
||||||
|
|
||||||
let work = config.prove_work(&phrase, DIFFICULTY).unwrap();
|
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_valid_proof(&work, &phrase));
|
||||||
assert!(config.is_sufficient_difficulty(&work, DIFFICULTY));
|
assert!(config.is_sufficient_difficulty(&work, DIFFICULTY));
|
||||||
}
|
}
|
||||||
|
|
BIN
main
Executable file
BIN
main
Executable file
Binary file not shown.
3
main.rs
Normal file
3
main.rs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
pub fn main() {
|
||||||
|
println!("{}", u128::MAX / 1000);
|
||||||
|
}
|
27
src/lib.rs
27
src/lib.rs
|
@ -12,10 +12,9 @@
|
||||||
//!
|
//!
|
||||||
//! let phrase = "ironmansucks";
|
//! let phrase = "ironmansucks";
|
||||||
//!
|
//!
|
||||||
//! const DIFFICULTY: u128 = u128::MAX / 32;
|
//! const DIFFICULTY: u32 = 1000;
|
||||||
//!
|
//!
|
||||||
//! let work = config.prove_work(&phrase, DIFFICULTY).unwrap();
|
//! 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_valid_proof(&work, &phrase));
|
||||||
//! assert!(config.is_sufficient_difficulty(&work, DIFFICULTY));
|
//! assert!(config.is_sufficient_difficulty(&work, DIFFICULTY));
|
||||||
//! }
|
//! }
|
||||||
|
@ -51,7 +50,7 @@ impl Config {
|
||||||
/// Make sure difficulty is not too high. A 64 bit difficulty,
|
/// Make sure difficulty is not too high. A 64 bit difficulty,
|
||||||
/// for example, takes a long time on a general purpose processor.
|
/// for example, takes a long time on a general purpose processor.
|
||||||
/// Returns bincode::Error if serialization fails.
|
/// Returns bincode::Error if serialization fails.
|
||||||
pub fn prove_work<T>(&self, t: &T, difficulty: u128) -> bincode::Result<PoW<T>>
|
pub fn prove_work<T>(&self, t: &T, difficulty: u32) -> bincode::Result<PoW<T>>
|
||||||
where
|
where
|
||||||
T: Serialize,
|
T: Serialize,
|
||||||
{
|
{
|
||||||
|
@ -63,14 +62,14 @@ impl Config {
|
||||||
///
|
///
|
||||||
/// Make sure difficulty is not too high. A 64 bit difficulty,
|
/// Make sure difficulty is not too high. A 64 bit difficulty,
|
||||||
/// for example, takes a long time on a general purpose processor.
|
/// for example, takes a long time on a general purpose processor.
|
||||||
pub fn prove_work_serialized<T>(&self, prefix: &[u8], difficulty: u128) -> PoW<T>
|
pub fn prove_work_serialized<T>(&self, prefix: &[u8], difficulty: u32) -> PoW<T>
|
||||||
where
|
where
|
||||||
T: Serialize,
|
T: Serialize,
|
||||||
{
|
{
|
||||||
let prefix_sha = Sha256::new().chain(&self.salt).chain(prefix);
|
let prefix_sha = Sha256::new().chain(&self.salt).chain(prefix);
|
||||||
let mut n = 0;
|
let mut n = 0;
|
||||||
let mut result = 0;
|
let mut result = 0;
|
||||||
while result < difficulty {
|
while result < get_difficulty(difficulty) {
|
||||||
n += 1;
|
n += 1;
|
||||||
result = score(prefix_sha.clone(), n);
|
result = score(prefix_sha.clone(), n);
|
||||||
}
|
}
|
||||||
|
@ -116,12 +115,12 @@ impl Config {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks if the PoW result is of sufficient difficulty
|
/// Checks if the PoW result is of sufficient difficulty
|
||||||
pub fn is_sufficient_difficulty<T>(&self, pow: &PoW<T>, target_diff: u128) -> bool
|
pub fn is_sufficient_difficulty<T>(&self, pow: &PoW<T>, target_diff: u32) -> bool
|
||||||
where
|
where
|
||||||
T: Serialize,
|
T: Serialize,
|
||||||
{
|
{
|
||||||
match pow.result.parse::<u128>() {
|
match pow.result.parse::<u128>() {
|
||||||
Ok(res) => return res >= target_diff,
|
Ok(res) => return res >= get_difficulty(target_diff),
|
||||||
Err(_) => return false,
|
Err(_) => return false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -143,11 +142,17 @@ fn first_bytes_as_u128(inp: &[u8]) -> u128 {
|
||||||
bincode::deserialize(&inp).unwrap()
|
bincode::deserialize(&inp).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// utility function to get u128 difficulty factor from u32
|
||||||
|
// javacript isn't capable of represnting u128 so
|
||||||
|
fn get_difficulty(difficulty_factor: u32) -> u128 {
|
||||||
|
u128::max_value() - u128::max_value() / difficulty_factor as u128
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
const DIFFICULTY: u128 = 0xff000000000000000000000000000000;
|
const DIFFICULTY: u32 = 1000;
|
||||||
|
|
||||||
fn get_config() -> Config {
|
fn get_config() -> Config {
|
||||||
ConfigBuilder::default()
|
ConfigBuilder::default()
|
||||||
|
@ -164,7 +169,7 @@ mod test {
|
||||||
let phrase = b"Ex nihilo nihil fit.".to_vec();
|
let phrase = b"Ex nihilo nihil fit.".to_vec();
|
||||||
let config = get_config();
|
let config = get_config();
|
||||||
let pw = config.prove_work(&phrase, DIFFICULTY).unwrap();
|
let pw = config.prove_work(&phrase, DIFFICULTY).unwrap();
|
||||||
assert!(config.calculate(&pw, &phrase).unwrap() >= DIFFICULTY);
|
assert!(config.calculate(&pw, &phrase).unwrap() >= get_difficulty(DIFFICULTY));
|
||||||
assert!(config.is_valid_proof(&pw, &phrase));
|
assert!(config.is_valid_proof(&pw, &phrase));
|
||||||
assert!(config.is_sufficient_difficulty(&pw, DIFFICULTY));
|
assert!(config.is_sufficient_difficulty(&pw, DIFFICULTY));
|
||||||
}
|
}
|
||||||
|
@ -177,11 +182,11 @@ mod test {
|
||||||
let pw = config.prove_work(&phrase, DIFFICULTY).unwrap();
|
let pw = config.prove_work(&phrase, DIFFICULTY).unwrap();
|
||||||
let pwpw = config.prove_work(&pw, DIFFICULTY).unwrap();
|
let pwpw = config.prove_work(&pw, DIFFICULTY).unwrap();
|
||||||
|
|
||||||
assert!(config.calculate(&pw, &phrase).unwrap() >= DIFFICULTY);
|
assert!(config.calculate(&pw, &phrase).unwrap() >= get_difficulty(DIFFICULTY));
|
||||||
assert!(config.is_valid_proof(&pw, &phrase));
|
assert!(config.is_valid_proof(&pw, &phrase));
|
||||||
assert!(config.is_sufficient_difficulty(&pw, DIFFICULTY));
|
assert!(config.is_sufficient_difficulty(&pw, DIFFICULTY));
|
||||||
|
|
||||||
assert!(config.calculate(&pwpw, &pw).unwrap() >= DIFFICULTY);
|
assert!(config.calculate(&pwpw, &pw).unwrap() >= get_difficulty(DIFFICULTY));
|
||||||
assert!(config.is_valid_proof(&pwpw, &pw));
|
assert!(config.is_valid_proof(&pwpw, &pw));
|
||||||
assert!(config.is_sufficient_difficulty(&pwpw, DIFFICULTY));
|
assert!(config.is_sufficient_difficulty(&pwpw, DIFFICULTY));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue