diff --git a/Makefile b/Makefile index 8ef8a39..6dd5fce 100644 --- a/Makefile +++ b/Makefile @@ -2,9 +2,6 @@ .PHONY: default vendor build doc install uninstall test coverage report clean -os-vendor: - sudo apt-get install libsecp256k1-dev --yes - vendor: opam install . --deps-only --yes @@ -37,9 +34,9 @@ doc: build test: build dune build @test/spec/runtest -f --no-buffer -j 1 -bench: os-vendor clean build +bench: clean build opam install core_bench --yes - opam install secp256k1 --yes + opam depext conf-secp256k1 secp256k1 --install dune build @test/bench/runtest -f --no-buffer -j 1 --auto-promote \ --diff-command="git diff --unified=10 --break-rewrites --no-index --exit-code --histogram --word-diff=none --color --no-prefix" || echo \ "\n\n=== Differences detected! ===\n\n" diff --git a/docs/coverage/index.html b/docs/coverage/index.html index 3ab0a7f..c14d7aa 100644 --- a/docs/coverage/index.html +++ b/docs/coverage/index.html @@ -110,6 +110,6 @@

100.00%

- + diff --git a/docs/coverage/lib/blacklist.ml.html b/docs/coverage/lib/blacklist.ml.html index 7f4eebf..a67cb7f 100644 --- a/docs/coverage/lib/blacklist.ml.html +++ b/docs/coverage/lib/blacklist.ml.html @@ -54,7 +54,7 @@

100.00%

- + diff --git a/docs/coverage/lib/encryption.ml.html b/docs/coverage/lib/encryption.ml.html index 4f0d67d..c1a07ed 100644 --- a/docs/coverage/lib/encryption.ml.html +++ b/docs/coverage/lib/encryption.ml.html @@ -63,13 +63,13 @@

100.00%

module Base64 = Nocrypto.Base64 let encrypt msg ~pass = - let key = of_secret (Cstruct.of_string (Hash.sha256 pass)) in + let key = of_secret (Hash.mine pass ~difficulty:6) in let result = encrypt ~key (Utils.pad ~basis:16 msg) in result |> Base64.encode |> Cstruct.to_string let decrypt cipher ~pass = - let key = of_secret (Cstruct.of_string (Hash.sha256 pass)) in + let key = of_secret (Hash.mine pass ~difficulty:6) in let result = cipher |> Cstruct.of_string |> Base64.decode in let open Option in result @@ -78,7 +78,7 @@

100.00%

- + diff --git a/docs/coverage/lib/hash.ml.html b/docs/coverage/lib/hash.ml.html index d9326f1..ad8c753 100644 --- a/docs/coverage/lib/hash.ml.html +++ b/docs/coverage/lib/hash.ml.html @@ -22,30 +22,72 @@

100.00%

- + + + + + + + + + + + + + + +
-1
-2
-3
-4
-5
-6
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
 
 let digest text =
   text |> Digestif.BLAKE2B.digest_string |> Digestif.BLAKE2B.to_hex
 
+let rec __mining input pattern nonce =
+  let length = Core.String.length pattern in
+  let salt = Nocrypto.Numeric.Z.to_cstruct_be nonce in
+  let message = Cstruct.append input salt in
+  let result = Nocrypto.Hash.SHA256.digest message in
+  let digest = Hex.show @@ Hex.of_cstruct result in
+  let part = Core.String.sub ~pos:0 ~len:length digest in
+  if pattern = part then
+    result
+  else
+    __mining input pattern @@ Z.succ nonce
 
-let sha256 text =
-  text |> Digestif.SHA256.digest_string |> Digestif.SHA256.to_raw_string
+let mine ~difficulty text =
+  let input = Cstruct.of_string text in
+  let nonce = Z.zero in
+  let pattern = Core.String.init difficulty ~f:(Core.const '0') in
+  __mining input pattern nonce
 
- + diff --git a/docs/coverage/lib/hieroglyphs.ml.html b/docs/coverage/lib/hieroglyphs.ml.html index d773de8..fea0f83 100644 --- a/docs/coverage/lib/hieroglyphs.ml.html +++ b/docs/coverage/lib/hieroglyphs.ml.html @@ -201,7 +201,7 @@

100.00%

- + diff --git a/docs/coverage/lib/keys.ml.html b/docs/coverage/lib/keys.ml.html index a13e9c7..3f8c29a 100644 --- a/docs/coverage/lib/keys.ml.html +++ b/docs/coverage/lib/keys.ml.html @@ -162,7 +162,7 @@

100.00%

- + diff --git a/docs/coverage/lib/random.ml.html b/docs/coverage/lib/random.ml.html index d4f531f..267ca41 100644 --- a/docs/coverage/lib/random.ml.html +++ b/docs/coverage/lib/random.ml.html @@ -42,7 +42,7 @@

100.00%

- + diff --git a/docs/coverage/lib/serialization.ml.html b/docs/coverage/lib/serialization.ml.html index 64051b8..5c614d6 100644 --- a/docs/coverage/lib/serialization.ml.html +++ b/docs/coverage/lib/serialization.ml.html @@ -72,7 +72,7 @@

100.00%

- + diff --git a/docs/coverage/lib/signing.ml.html b/docs/coverage/lib/signing.ml.html index 766deba..d25587a 100644 --- a/docs/coverage/lib/signing.ml.html +++ b/docs/coverage/lib/signing.ml.html @@ -48,7 +48,7 @@

100.00%

- + diff --git a/docs/coverage/lib/store.ml.html b/docs/coverage/lib/store.ml.html index 1739e9c..498f415 100644 --- a/docs/coverage/lib/store.ml.html +++ b/docs/coverage/lib/store.ml.html @@ -204,7 +204,7 @@

100.00%

- + diff --git a/docs/coverage/lib/utils.ml.html b/docs/coverage/lib/utils.ml.html index a0232f5..99596bd 100644 --- a/docs/coverage/lib/utils.ml.html +++ b/docs/coverage/lib/utils.ml.html @@ -194,7 +194,7 @@

100.00%

let id value = value let is_hash text = - Str.string_match regexp text 0 && String.length text = _HASH_LENGTH + Str.string_match regexp text 0 && String.length text = _HASH_LENGTH let validate_key list = @@ -255,7 +255,7 @@

100.00%

- + diff --git a/docs/coverage/lib/verification.ml.html b/docs/coverage/lib/verification.ml.html index e302a49..bb41112 100644 --- a/docs/coverage/lib/verification.ml.html +++ b/docs/coverage/lib/verification.ml.html @@ -51,7 +51,7 @@

100.00%

- + diff --git a/lib/encryption.ml b/lib/encryption.ml index cb07e55..cbf9437 100644 --- a/lib/encryption.ml +++ b/lib/encryption.ml @@ -3,13 +3,13 @@ module Option = Core.Option module Base64 = Nocrypto.Base64 let encrypt msg ~pass = - let key = of_secret (Cstruct.of_string (Hash.sha256 pass)) in + let key = of_secret (Hash.mine pass ~difficulty:6) in let result = encrypt ~key (Utils.pad ~basis:16 msg) in result |> Base64.encode |> Cstruct.to_string let decrypt cipher ~pass = - let key = of_secret (Cstruct.of_string (Hash.sha256 pass)) in + let key = of_secret (Hash.mine pass ~difficulty:6) in let result = cipher |> Cstruct.of_string |> Base64.decode in let open Option in result diff --git a/lib/hash.ml b/lib/hash.ml index 4784004..42a4fbb 100644 --- a/lib/hash.ml +++ b/lib/hash.ml @@ -2,5 +2,18 @@ let digest text = text |> Digestif.BLAKE2B.digest_string |> Digestif.BLAKE2B.to_hex -let sha256 text = - text |> Digestif.SHA256.digest_string |> Digestif.SHA256.to_raw_string +let rec __mining input pattern nonce = + let length = Core.String.length pattern in + let salt = Nocrypto.Numeric.Z.to_cstruct_be nonce in + let message = Cstruct.append input salt in + let result = Nocrypto.Hash.SHA256.digest message in + let digest = Hex.show @@ Hex.of_cstruct result in + let part = Core.String.sub ~pos:0 ~len:length digest in + if pattern = part then result else __mining input pattern @@ Z.succ nonce + + +let mine ~difficulty text = + let input = Cstruct.of_string text in + let nonce = Z.zero in + let pattern = Core.String.init difficulty ~f:(Core.const '0') in + __mining input pattern nonce diff --git a/lib/hash.mli b/lib/hash.mli index 56c315b..8686d70 100644 --- a/lib/hash.mli +++ b/lib/hash.mli @@ -1,3 +1,3 @@ val digest : string -> string -val sha256 : string -> string +val mine : difficulty:int -> string -> Cstruct.t diff --git a/test/bench/bench.expected b/test/bench/bench.expected index 86b8e15..3dae249 100644 --- a/test/bench/bench.expected +++ b/test/bench/bench.expected @@ -2,18 +2,18 @@ Estimated testing time 2m (12 benchmarks x 10s). Change using -quota SECS. ┌─────────────────────────────────────────────────────┬────────────────────┬───────────────┬─────────────────┬─────────────┬────────────┐ │ Name │ Time/Run │ mWd/Run │ mjWd/Run │ Prom/Run │ Percentage │ ├─────────────────────────────────────────────────────┼────────────────────┼───────────────┼─────────────────┼─────────────┼────────────┤ -│ hieroglyphs + blake2b ------ private key generation │ 426_575_117.35ns │ 1_027_102.98w │ 33_922_454.02w │ 88_379.02w │ 23.10% │ -│ hieroglyphs + blake2b ------ message signing │ 1_846_300_673.37ns │ 6_296_025.80w │ 102_379_701.20w │ 610_674.40w │ 100.00% │ -│ hieroglyphs + blake2b ------ public key derivation │ 9_932_526.22ns │ 206_848.85w │ 15_398.83w │ 15_398.83w │ 0.54% │ -│ hieroglyphs + blake2b ------ signature verification │ 2_162_206.86ns │ 21_148.32w │ 114.85w │ 114.85w │ 0.12% │ -│ rsa pss/sha256 1024 bits --- private key generation │ 37_738_427.50ns │ 870.88w │ -0.23w │ -0.23w │ 2.04% │ -│ rsa pss/sha256 1024 bits --- public key derivation │ 9.88ns │ 3.00w │ │ │ │ -│ rsa pss/sha256 1024 bits --- message signing │ 788_808.95ns │ 1_715.19w │ 0.59w │ 0.59w │ 0.04% │ -│ rsa pss/sha256 1024 bits --- signature verification │ 90_419.45ns │ 1_547.02w │ 0.34w │ 0.34w │ │ -│ secp256k1 + sha256 hash ---- private key generation │ 13_287.47ns │ 355.70w │ │ │ │ -│ secp256k1 + sha256 hash ---- public key derivation │ 217_163.38ns │ 13.00w │ │ │ 0.01% │ -│ secp256k1 + sha256 hash ---- message signing │ 469_056.14ns │ 585.39w │ 0.15w │ 0.15w │ 0.03% │ -│ secp256k1 + sha256 hash ---- signature verification │ 456_386.78ns │ 214.00w │ │ │ 0.02% │ +│ hieroglyphs + blake2b ------ private key generation │ 376_317_374.97ns │ 1_037_742.79w │ 33_922_480.27w │ 88_405.27w │ 28.36% │ +│ hieroglyphs + blake2b ------ message signing │ 1_326_859_831.73ns │ 7_161_043.30w │ 102_462_832.00w │ 689_212.00w │ 100.00% │ +│ hieroglyphs + blake2b ------ public key derivation │ 6_672_776.35ns │ 206_848.86w │ 15_337.63w │ 15_337.63w │ 0.50% │ +│ hieroglyphs + blake2b ------ signature verification │ 1_896_086.08ns │ 21_148.32w │ 115.42w │ 115.42w │ 0.14% │ +│ rsa pss/sha256 1024 bits --- private key generation │ 35_003_683.96ns │ 870.97w │ -0.23w │ -0.23w │ 2.64% │ +│ rsa pss/sha256 1024 bits --- public key derivation │ 10.18ns │ 3.00w │ │ │ │ +│ rsa pss/sha256 1024 bits --- message signing │ 709_147.00ns │ 1_715.04w │ 0.56w │ 0.56w │ 0.05% │ +│ rsa pss/sha256 1024 bits --- signature verification │ 81_176.42ns │ 1_547.02w │ 0.34w │ 0.34w │ │ +│ secp256k1 + sha256 hash ---- private key generation │ 13_894.85ns │ 355.67w │ │ │ │ +│ secp256k1 + sha256 hash ---- public key derivation │ 259_270.15ns │ 13.00w │ │ │ 0.02% │ +│ secp256k1 + sha256 hash ---- message signing │ 336_969.12ns │ 585.77w │ 0.15w │ 0.15w │ 0.03% │ +│ secp256k1 + sha256 hash ---- signature verification │ 363_144.00ns │ 214.00w │ │ │ 0.03% │ └─────────────────────────────────────────────────────┴────────────────────┴───────────────┴─────────────────┴─────────────┴────────────┘ Benchmarks that take 1ns to 100ms can be estimated precisely. For more reliable estimates, redesign your benchmark to have a shorter execution time.