u32 difficulty factor

This commit is contained in:
Aravinth Manivannan 2021-03-08 18:27:18 +05:30
parent e5b4baab3f
commit d1473ae5aa
Signed by: realaravinth
GPG key ID: AD9F0F08E855ED88
8 changed files with 38 additions and 19 deletions

8
CHANGELOG.md Normal file
View 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
View file

@ -138,7 +138,7 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
[[package]]
name = "pow_sha256"
version = "0.1.0"
version = "0.1.1"
dependencies = [
"bincode",
"derive_builder",

View file

@ -1,6 +1,6 @@
[package]
name = "pow_sha256"
version = "0.1.0"
version = "0.1.1"
authors = [ "Aravinth Manivannan <realaravinth@bastsense.net>", "Robert Kornacki <robk@syre.io>"]
description = """
SHA256 PoW on any serializable datatype used in mCaptcha

View file

@ -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
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
unique salts.
@ -50,7 +50,7 @@ fn main() {
let phrase = "ironmansucks";
const DIFFICULTY: u128 = u128::MAX / 32;
const DIFFICULTY: u32 = 1000;
let work = config.prove_work(&phrase, DIFFICULTY).unwrap();
assert!(config.calculate(&work, &phrase).unwrap() >= DIFFICULTY);
@ -76,7 +76,7 @@ fn main() {
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();
@ -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`.

View file

@ -12,10 +12,9 @@ fn main() {
let phrase = "ironmansucks";
const DIFFICULTY: u128 = u128::MAX / 32;
const DIFFICULTY: u32 = 1000;
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_sufficient_difficulty(&work, DIFFICULTY));
}

BIN
main Executable file

Binary file not shown.

3
main.rs Normal file
View file

@ -0,0 +1,3 @@
pub fn main() {
println!("{}", u128::MAX / 1000);
}

View file

@ -12,10 +12,9 @@
//!
//! let phrase = "ironmansucks";
//!
//! const DIFFICULTY: u128 = u128::MAX / 32;
//! const DIFFICULTY: u32 = 1000;
//!
//! 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_sufficient_difficulty(&work, DIFFICULTY));
//! }
@ -51,7 +50,7 @@ impl Config {
/// Make sure difficulty is not too high. A 64 bit difficulty,
/// for example, takes a long time on a general purpose processor.
/// 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
T: Serialize,
{
@ -63,14 +62,14 @@ impl Config {
///
/// Make sure difficulty is not too high. A 64 bit difficulty,
/// 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
T: Serialize,
{
let prefix_sha = Sha256::new().chain(&self.salt).chain(prefix);
let mut n = 0;
let mut result = 0;
while result < difficulty {
while result < get_difficulty(difficulty) {
n += 1;
result = score(prefix_sha.clone(), n);
}
@ -116,12 +115,12 @@ impl Config {
}
/// 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
T: Serialize,
{
match pow.result.parse::<u128>() {
Ok(res) => return res >= target_diff,
Ok(res) => return res >= get_difficulty(target_diff),
Err(_) => return false,
}
}
@ -143,11 +142,17 @@ fn first_bytes_as_u128(inp: &[u8]) -> u128 {
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)]
mod test {
use super::*;
const DIFFICULTY: u128 = 0xff000000000000000000000000000000;
const DIFFICULTY: u32 = 1000;
fn get_config() -> Config {
ConfigBuilder::default()
@ -164,7 +169,7 @@ mod test {
let phrase = b"Ex nihilo nihil fit.".to_vec();
let config = get_config();
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_sufficient_difficulty(&pw, DIFFICULTY));
}
@ -177,11 +182,11 @@ mod test {
let pw = config.prove_work(&phrase, 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_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_sufficient_difficulty(&pwpw, DIFFICULTY));
}