diff --git a/.gitignore b/.gitignore index 64ddfa5ca..fae022dc8 100644 --- a/.gitignore +++ b/.gitignore @@ -13,4 +13,8 @@ compilers/concrete-compiler/compiler/hpx* tmp_directory_for_cml_tests # Temp file -frontends/concrete-python/examples/sha1/tmp_sha1_test_file.txt \ No newline at end of file +<<<<<<< HEAD +frontends/concrete-python/examples/sha1/tmp_sha1_test_file.txt +======= +frontends/concrete-python/examples/sha1/tmp_sha1_test_file.txt +>>>>>>> 78decb21 (docs(frontend): adding a SHA1 tutorial with modules) diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index 856fe2347..98f0eb532 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -28,11 +28,11 @@ ## Compilation * [Composition](compilation/composition.md) +* [Modules](compilation/modules.md) * [Compression](compilation/compression.md) * [Reuse arguments](compilation/reuse_arguments.md) * [Multi precision](compilation/multi_precision.md) * [Multi parameters](compilation/multi_parameters.md) -* [Modules](compilation/modules.md) * [Decorator](compilation/decorator.md) * [Direct circuits](compilation/direct_circuits.md) diff --git a/docs/tutorials/see-all-tutorials.md b/docs/tutorials/see-all-tutorials.md index ed8a8781d..8e59b7226 100644 --- a/docs/tutorials/see-all-tutorials.md +++ b/docs/tutorials/see-all-tutorials.md @@ -13,6 +13,7 @@ * [SHA-256 ](../application-tutorial/sha256.ipynb) * [Game of Life](../../frontends/concrete-python/examples/game_of_life/game_of_life.md) * [XOR distance](../../frontends/concrete-python/examples/xor_distance/xor_distance.md) +* [SHA1 with Modules](../../frontends/concrete-python/examples/sha1/sha1.md) #### Blog tutorials diff --git a/frontends/concrete-python/examples/sha1/sha1.md b/frontends/concrete-python/examples/sha1/sha1.md index 0e9c515ce..c0e0139ce 100644 --- a/frontends/concrete-python/examples/sha1/sha1.md +++ b/frontends/concrete-python/examples/sha1/sha1.md @@ -151,6 +151,11 @@ functions in FHE. Compiling with `show_mlir = True` allows to see the different MLIR implementations. Typically, with current Concrete version, it would give something like: +<<<<<<< HEAD +======= +- `add2` function +
+>>>>>>> 78decb21 (docs(frontend): adding a SHA1 tutorial with modules) ``` func.func @add2(%arg0: tensor<32x!FHE.eint<2>>, %arg1: tensor<32x!FHE.eint<2>>) -> tensor<32x!FHE.eint<2>> { %0 = "FHE.zero_tensor"() : () -> tensor<32x!FHE.eint<2>> @@ -448,7 +453,14 @@ current Concrete version, it would give something like: return %inserted_slice_125 : tensor<32x!FHE.eint<2>> } ``` +<<<<<<< HEAD +======= +
+ +- `add5` function +
+>>>>>>> 78decb21 (docs(frontend): adding a SHA1 tutorial with modules) ``` func.func @add5(%arg0: tensor<32x!FHE.eint<2>>, %arg1: tensor<32x!FHE.eint<2>>, %arg2: tensor<32x!FHE.eint<2>>, %arg3: tensor<32x!FHE.eint<2>>, %arg4: tensor<32x!FHE.eint<2>>) -> tensor<32x!FHE.eint<2>> { %0 = "FHE.zero_tensor"() : () -> tensor<32x!FHE.eint<2>> @@ -1511,7 +1523,14 @@ current Concrete version, it would give something like: return %inserted_slice_509 : tensor<32x!FHE.eint<2>> } ``` +<<<<<<< HEAD +======= +
+ +- `iftern` function +
+>>>>>>> 78decb21 (docs(frontend): adding a SHA1 tutorial with modules) ``` func.func @iftern(%arg0: tensor<32x!FHE.eint<2>>, %arg1: tensor<32x!FHE.eint<2>>, %arg2: tensor<32x!FHE.eint<2>>) -> tensor<32x!FHE.eint<2>> { %c2_i3 = arith.constant 2 : i3 @@ -1530,7 +1549,14 @@ current Concrete version, it would give something like: return %8 : tensor<32x!FHE.eint<2>> } ``` +<<<<<<< HEAD +======= +
+ +- `maj` function +
+>>>>>>> 78decb21 (docs(frontend): adding a SHA1 tutorial with modules) ``` func.func @maj(%arg0: tensor<32x!FHE.eint<2>>, %arg1: tensor<32x!FHE.eint<2>>, %arg2: tensor<32x!FHE.eint<2>>) -> tensor<32x!FHE.eint<2>> { %c2_i3 = arith.constant 2 : i3 @@ -1550,7 +1576,14 @@ current Concrete version, it would give something like: return %9 : tensor<32x!FHE.eint<2>> } ``` +<<<<<<< HEAD +======= +
+ +- `rotate30` function +
+>>>>>>> 78decb21 (docs(frontend): adding a SHA1 tutorial with modules) ``` func.func @rotate30(%arg0: tensor<32x!FHE.eint<2>>) -> tensor<32x!FHE.eint<2>> { %0 = "FHE.zero_tensor"() : () -> tensor<32x!FHE.eint<2>> @@ -1561,7 +1594,14 @@ current Concrete version, it would give something like: return %inserted_slice_1 : tensor<32x!FHE.eint<2>> } ``` +<<<<<<< HEAD +======= +
+ +- `rotate5` function +
+>>>>>>> 78decb21 (docs(frontend): adding a SHA1 tutorial with modules) ``` func.func @rotate5(%arg0: tensor<32x!FHE.eint<2>>) -> tensor<32x!FHE.eint<2>> { %0 = "FHE.zero_tensor"() : () -> tensor<32x!FHE.eint<2>> @@ -1572,7 +1612,14 @@ current Concrete version, it would give something like: return %inserted_slice_1 : tensor<32x!FHE.eint<2>> } ``` +<<<<<<< HEAD +======= +
+ +- `xor3` function +
+>>>>>>> 78decb21 (docs(frontend): adding a SHA1 tutorial with modules) ``` func.func @xor3(%arg0: tensor<32x!FHE.eint<2>>, %arg1: tensor<32x!FHE.eint<2>>, %arg2: tensor<32x!FHE.eint<2>>) -> tensor<32x!FHE.eint<2>> { %c2_i3 = arith.constant 2 : i3 @@ -1588,6 +1635,10 @@ current Concrete version, it would give something like: } } ``` +<<<<<<< HEAD +======= +
+>>>>>>> 78decb21 (docs(frontend): adding a SHA1 tutorial with modules) ## Testing or Using @@ -1599,8 +1650,100 @@ One can check that the implementation works in FHE by running `python sha1.py -- pick a certain number of random inputs, hash them in FHE and compare the result with the `hashlib` standard implementation. +<<<<<<< HEAD One can also hash a given value with: `` +======= +One can also hash a given value with +`echo -n "The quick brown fox jumps over the lazy dog" | python sha1.py`, and it will print +something like: + +``` +sha1-digest: 2fd4e1c67a2d28fced849ee1bb76e7391b93eb12 +computed in: 320.265383 seconds +``` + +## Benchmarks + +We have executed our implementation on an HPC7a machine with Concrete 2.7.0rc1. + +`python sha1.py --autotest` typically returns: + +``` +Checking SHA1(fdASguUMBwhPcKuDpPqoRlQXLrLQbnxEvPJSQSIUDTBoaqrJlBualgoWEINmDZDYSuGuSOpGBWwWzjAfktWYZZUliv) for an input length 90 +sha1-digest: 5bb539fd423875ccc8a33148dae724f5b2cf9391 +computed in: 295.306287 seconds +Checking SHA1(BYwXTbqE) for an input length 8 +sha1-digest: 90a8dcad6ddff7ca8fd487b80a37fcd250c56bed +computed in: 145.341164 seconds +Checking SHA1(rnPZh) for an input length 5 +sha1-digest: 47610d2c26ee8b45ab0f4c8f8e4d405b2cd37f1f +computed in: 145.318081 seconds +Checking SHA1(orRaJMGbUJtxITQvqiOCPjKJWYuHomuiexCQQgZyTeAAFJcgCftDCRAkcLKjRECelIMPQphGEUlSNthE) for an input length 80 +sha1-digest: bd74b4e64349d308f3b95b54cf61ee416bdd6b18 +computed in: 288.240576 seconds +Checking SHA1(ROokDcdczajNPjlCPoWotaRJHBtOVyiyxMIIeCtxaDCjk) for an input length 45 +sha1-digest: 1ff546c3a64f27339781c095cbc097f392c2cccd +computed in: 143.621941 seconds +Checking SHA1(KbCXFt) for an input length 6 +sha1-digest: 7e5789f0c83fa5102004fbeeef3ac22244d1cdac +computed in: 143.509567 seconds +Checking SHA1(mpKnkHtrgokxgQSzcIjFtxKnhmMfZbIbkJavnkSxW) for an input length 41 +sha1-digest: 1308d9f7cba634ab2617edb5116b8bdf434f16f5 +computed in: 143.341450 seconds +Checking SHA1(oauoWKJGyjjTcXqRIxFGuVuMwiwjKYfttQ) for an input length 34 +sha1-digest: 60367153b7049ca92eb979ad7b809c5a3f47a64e +computed in: 143.693254 seconds +Checking SHA1(ZMGiaIOmBJPncOsUCxj) for an input length 19 +sha1-digest: fafba9f2fe6b5a0fddad4ad765909c8fc32117c6 +computed in: 143.720215 seconds +Checking SHA1(HwCXIHnFoGUgIBqaQrrpDnhEvPBX) for an input length 28 +sha1-digest: 5224cace20f8d20fa3ea8d9974b5ff3a0be7fd48 +computed in: 143.523006 seconds +Checking SHA1(AfyzsimngrqeWoqZKOBRwVuvttfgJTpegMbiHjUNdWzTg) for an input length 45 +sha1-digest: 8ca27aca1c362ca63e50d58aa7065b4322f028a0 +computed in: 143.481069 seconds +Checking SHA1(hNEUPakrqQpGGZvtHvht) for an input length 20 +sha1-digest: 36ae34ed85e62ac0f922e36fc98b23e725695be1 +computed in: 143.478666 seconds +Checking SHA1(CjgfYYlNKqZdHeXFfqTwhycbGBeSpzpxKPwWItriiNKZCcEJRZlM) for an input length 52 +sha1-digest: 3c012f41c5fe4581f80e2901fc4bbbb70ff7a9ba +computed in: 143.490262 seconds +Checking SHA1(EXIGkYzWpcqpfRKCSbBJJqqmUBkFwWfPGooJvsVAshWjMr) for an input length 46 +sha1-digest: 2518c4d13ec7608f59632ac993b726e572c3aaae +computed in: 143.840785 seconds +Checking SHA1(sgzaAqZnhXmFJOJMyfGxweYFMmLeUHmMCWETfqzstzpFYKaGpnasiLHPTcJtukHztEQpXzquREcbtoJDaoqjfM) for an input length 86 +sha1-digest: 46f4b0653ed7ea0ce89cc18f6720e5e334d63a45 +computed in: 288.155301 seconds +Checking SHA1(oRaisdHJovDxCnwyComEGejqMceBTOVhJucVnwgC) for an input length 40 +sha1-digest: 909f9c6275aa9f41d8ecaf52203bb0e24cf978d7 +computed in: 143.466817 seconds +Checking SHA1(mtTWxtHerQgLdBGftWdiCwBKqtu) for an input length 27 +sha1-digest: 624a7dcec460061a2a6499dae978fe4afd674110 +computed in: 145.389956 seconds +Checking SHA1(beYzkJLvZMmoXbQwqoVThpyaQ) for an input length 25 +sha1-digest: 25a9df47bd055384a9ee614c1dc7213c04f2087c +computed in: 147.234881 seconds +Checking SHA1(CpQWXXRNlXIoSZNxmXUwWHqmUAdlOrDyZPzzOhznlpGntrUgvktlZ) for an input length 53 +sha1-digest: f2bde6574d8f6aa360929f6a5f919700b16e093b +computed in: 147.154393 seconds +Checking SHA1(busWigrVdsXnkjTh) for an input length 16 +sha1-digest: fe47568d433278a38a4729f7891d03eaacdb0e40 +computed in: 147.465694 seconds +Checking SHA1() +sha1-digest: da39a3ee5e6b4b0d3255bfef95601890afd80709 +computed in: 147.256297 seconds +Checking SHA1(The quick brown fox jumps over the lazy dog) +sha1-digest: 2fd4e1c67a2d28fced849ee1bb76e7391b93eb12 +computed in: 147.697102 seconds +``` + +means that: +- one block of compression takes about 147 seconds +- two blocks of compression take about 290 seconds + + +>>>>>>> 78decb21 (docs(frontend): adding a SHA1 tutorial with modules) diff --git a/frontends/concrete-python/examples/sha1/sha1.py b/frontends/concrete-python/examples/sha1/sha1.py index df7434c7c..3ccd09def 100755 --- a/frontends/concrete-python/examples/sha1/sha1.py +++ b/frontends/concrete-python/examples/sha1/sha1.py @@ -21,6 +21,7 @@ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +<<<<<<< HEAD import struct import io import numpy @@ -30,6 +31,18 @@ import string from concrete import fhe from hashlib import sha1 as hashlib_sha1 +======= +import io +import random +import string +import struct +import time +from hashlib import sha1 as hashlib_sha1 + +import numpy + +from concrete import fhe +>>>>>>> 78decb21 (docs(frontend): adding a SHA1 tutorial with modules) def _left_rotate(n, b): @@ -187,6 +200,10 @@ my_module = MyModule.compile( p_error=10**-8, ) +<<<<<<< HEAD +======= + +>>>>>>> 78decb21 (docs(frontend): adding a SHA1 tutorial with modules) # Split and encrypt on the client side def message_schedule_and_split_and_encrypt(chunk): @@ -419,8 +436,13 @@ def print_timed_sha1(data): if __name__ == "__main__": # Imports required for command line parsing. No need for these elsewhere import argparse +<<<<<<< HEAD import sys import os +======= + import os + import sys +>>>>>>> 78decb21 (docs(frontend): adding a SHA1 tutorial with modules) # Parse the incoming arguments parser = argparse.ArgumentParser()