Skip to content

Commit

Permalink
refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
juerg committed Dec 12, 2023
1 parent ed7bce6 commit 4072588
Show file tree
Hide file tree
Showing 15 changed files with 477 additions and 430 deletions.
4 changes: 2 additions & 2 deletions doc/examples/scripts/aes-speed.venice
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,10 @@
(printf "%-21s %4dms%n" title elapsed))

(defn encrypt [algo passphrase file-in file-out]
(crypt/encrypt-file algo file-in file-out passphrase))
(crypt/encrypt-file algo passphrase file-in file-out))

(defn decrypt [algo passphrase file-in file-out]
(crypt/decrypt-file algo file-in file-out passphrase))
(crypt/decrypt-file algo passphrase file-in file-out))

(defn encrypt-zip [zip passphrase filename file ]
(zipvault/zip zip passphrase filename (io/slurp file :binary true)))
Expand Down
8 changes: 2 additions & 6 deletions doc/examples/scripts/hash-speed.venice
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,6 @@
(defonce test-dir (io/file (io/user-home-dir) "Desktop/venice/tmp"))


(defn identical [file1 file2]
(= (io/slurp file1 :binary true)
(io/slurp file2 :binary true)))

(defn printel [title elapsed]
(printf "%-20s %4dms%n" title elapsed))

Expand All @@ -73,13 +69,13 @@

;; file based: MD5, SHA-1, SHA-256
(docoll (fn [algo]
(->> (timing/elapsed #(crypt/hash-file file salt algo))
(->> (timing/elapsed #(crypt/hash-file algo salt file))
(printel (str "Hash " algo " (file):"))))
algos)

;; memory based: MD5, SHA-1, SHA-256
(docoll (fn [algo]
(->> (timing/elapsed #(crypt/hash-file data salt algo))
(->> (timing/elapsed #(crypt/hash-file algo salt data))
(printel (str "Hash " algo " (mem):"))))
algos)))

Expand Down
69 changes: 65 additions & 4 deletions doc/readme/cryptography.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@

## File encryption

Venice supports encrypting and decrypting files and buffers using AES and ChaCha20, both with 256 bit keys:
Venice supports encrypting and decrypting files, streams and buffers using
AES and ChaCha20, both with 256 bit keys:

* AES256-GCM ¹⁾
* AES256-CBC ²⁾
Expand Down Expand Up @@ -43,6 +44,7 @@ RISC nature.
```
(do
(load-module :crypt)
(let [algo "AES256-GCM" ;; "AES256-CBC", "AES256-GCM, "ChaCha20", "ChaCha20-BC"
data (bytebuf-allocate-random 100)
file-in (io/temp-file "test-", ".data")
Expand All @@ -51,8 +53,8 @@ RISC nature.
(io/delete-file-on-exit file-in file-enc file-dec)
(io/spit file-in data :binary true)
(crypt/encrypt-file algo file-in file-enc "-passphrase-")
(crypt/decrypt-file algo file-enc file-dec "-passphrase-")))
(crypt/encrypt-file algo "-passphrase-" file-in file-enc)
(crypt/decrypt-file algo "-passphrase-" file-enc file-dec)))
```

`crypt/encrypt-file` and `crypt/decrypt-file` work both on files, streams
Expand All @@ -64,12 +66,13 @@ and memory buffers.
```
(do
(load-module :zipvault)
(let [data (bytebuf-allocate-random 100)
file-in (io/temp-file "test-", ".data")
file-zip (io/temp-file "test-", ".data.zip")
file-unzip (io/temp-file "test-", ".data.unzip")
entry-name (io/file-name file-unzip)
dest-dir (io/file-parent aes-file-unzip)]
dest-dir (io/file-parent file-unzip)]
(io/delete-file-on-exit file-in file-zip file-unzip)
(io/spit file-in data :binary true)
Expand Down Expand Up @@ -122,3 +125,61 @@ Decrypt ChaCha20-BC: 74ms 73ms 74ms 85ms 160ms 931ms

## File hashing

Venice computes hashes for files, streams, and buffers with the
algorithms MD5, SHA-1, and SHA-256.

Warning: The MD5 hash function’s security is considered to be
severely compromised. Collisions can be found within seconds,
and they can be used for malicious purposes.


### Examples

**SHA-1**

```
(do
(load-module :crypt)
(let [data (bytebuf-allocate-random 100)
file (io/temp-file "test-", ".data")]
(io/delete-file-on-exit file)
(io/spit file data :binary true)
(let [hash (crypt/hash-file "SHA-1" "-salt-" file)]
(crypt/verify-file-hash "SHA-1" "-salt-" file hash))))
```


**SHA-256**

```
(do
(load-module :crypt)
(let [data (bytebuf-allocate-random 100)
file (io/temp-file "test-", ".data")]
(io/delete-file-on-exit file)
(io/spit file data :binary true)
(let [hash (crypt/hash-file "SHA-256" "-salt-" file)]
(crypt/verify-file-hash "SHA-256" "-salt-" file hash))))
```


### Perfomance


```
MacBookAir M2, Java 8 (Zulu)
--------------------------------------------------------------------
2KB 20KB 200KB 2MB 20MB 200MB
--------------------------------------------------------------------
Hash MD5 (file): 1ms 1ms 1ms 6ms 56ms 547ms
Hash SHA-1 (file): 0ms 1ms 2ms 7ms 65ms 685ms
Hash SHA-256 (file): 0ms 0ms 2ms 8ms 77ms 764ms
Hash MD5 (memory): 0ms 1ms 1ms 5ms 54ms 535ms
Hash SHA-1 (memory): 0ms 1ms 1ms 7ms 64ms 642ms
Hash SHA-256 (memory): 1ms 0ms 1ms 8ms 76ms 749ms
--------------------------------------------------------------------
```
Original file line number Diff line number Diff line change
Expand Up @@ -33,22 +33,22 @@ public class FileEncryptor {

public static void encryptFileWithPassphrase(
final String algorithm,
final String passphrase,
final File inputFile,
final File outputFile,
final String passphrase
final File outputFile
) throws Exception {
switch(StringUtil.trimToEmpty(algorithm).toUpperCase()) {
case "AES256-CBC":
FileEncryptor_AES256_CBC.encryptFileWithPassphrase(inputFile, outputFile, passphrase);
FileEncryptor_AES256_CBC.encryptFileWithPassphrase(passphrase, inputFile, outputFile);
break;
case "AES256-GCM":
FileEncryptor_AES256_GCM.encryptFileWithPassphrase(inputFile, outputFile, passphrase);
FileEncryptor_AES256_GCM.encryptFileWithPassphrase(passphrase, inputFile, outputFile);
break;
case "CHACHA20":
FileEncryptor_ChaCha20.encryptFileWithPassphrase(inputFile, outputFile, passphrase);
FileEncryptor_ChaCha20.encryptFileWithPassphrase(passphrase, inputFile, outputFile);
break;
case "CHACHA20-BC":
FileEncryptor_ChaCha20_BouncyCastle.encryptFileWithPassphrase(inputFile, outputFile, passphrase);
FileEncryptor_ChaCha20_BouncyCastle.encryptFileWithPassphrase(passphrase, inputFile, outputFile);
break;
default:
throw new RuntimeException("Unsupported algorith '" + algorithm + "'!");
Expand All @@ -57,41 +57,41 @@ public static void encryptFileWithPassphrase(

public static byte[] encryptFileWithPassphrase(
final String algorithm,
final byte[] fileData,
final String passphrase
final String passphrase,
final byte[] fileData
) throws Exception {
switch(StringUtil.trimToEmpty(algorithm).toUpperCase()) {
case "AES256-CBC":
return FileEncryptor_AES256_CBC.encryptFileWithPassphrase(fileData, passphrase);
return FileEncryptor_AES256_CBC.encryptFileWithPassphrase(passphrase, fileData);
case "AES256-GCM":
return FileEncryptor_AES256_GCM.encryptFileWithPassphrase(fileData, passphrase);
return FileEncryptor_AES256_GCM.encryptFileWithPassphrase(passphrase, fileData);
case "CHACHA20":
return FileEncryptor_ChaCha20.encryptFileWithPassphrase(fileData, passphrase);
return FileEncryptor_ChaCha20.encryptFileWithPassphrase(passphrase, fileData);
case "CHACHA20-BC":
return FileEncryptor_ChaCha20_BouncyCastle.encryptFileWithPassphrase(fileData, passphrase);
return FileEncryptor_ChaCha20_BouncyCastle.encryptFileWithPassphrase(passphrase, fileData);
default:
throw new RuntimeException("Unsupported algorith '" + algorithm + "'!");
}
}

public static void encryptFileWithKey(
final String algorithm,
final byte[] key,
final File inputFile,
final File outputFile,
final byte[] key
final File outputFile
) throws Exception {
switch(StringUtil.trimToEmpty(algorithm).toUpperCase()) {
case "AES256-CBC":
FileEncryptor_AES256_CBC.encryptFileWithKey(inputFile, outputFile, key);
FileEncryptor_AES256_CBC.encryptFileWithKey(key, inputFile, outputFile);
break;
case "AES256-GCM":
FileEncryptor_AES256_GCM.encryptFileWithKey(inputFile, outputFile, key);
FileEncryptor_AES256_GCM.encryptFileWithKey(key, inputFile, outputFile);
break;
case "CHACHA20":
FileEncryptor_ChaCha20.encryptFileWithKey(inputFile, outputFile, key);
FileEncryptor_ChaCha20.encryptFileWithKey(key, inputFile, outputFile);
break;
case "CHACHA20-BC":
FileEncryptor_ChaCha20_BouncyCastle.encryptFileWithKey(inputFile, outputFile, key);
FileEncryptor_ChaCha20_BouncyCastle.encryptFileWithKey(key, inputFile, outputFile);
break;
default:
throw new RuntimeException("Unsupported algorith '" + algorithm + "'!");
Expand All @@ -100,41 +100,41 @@ public static void encryptFileWithKey(

public static byte[] encryptFileWithKey(
final String algorithm,
final byte[] fileData,
final byte[] key
final byte[] key,
final byte[] fileData
) throws Exception {
switch(StringUtil.trimToEmpty(algorithm).toUpperCase()) {
case "AES256-CBC":
return FileEncryptor_AES256_CBC.encryptFileWithKey(fileData, key);
return FileEncryptor_AES256_CBC.encryptFileWithKey(key, fileData);
case "AES256-GCM":
return FileEncryptor_AES256_GCM.encryptFileWithKey(fileData, key);
return FileEncryptor_AES256_GCM.encryptFileWithKey(key, fileData);
case "CHACHA20":
return FileEncryptor_ChaCha20.encryptFileWithKey(fileData, key);
return FileEncryptor_ChaCha20.encryptFileWithKey(key, fileData);
case "CHACHA20-BC":
return FileEncryptor_ChaCha20_BouncyCastle.encryptFileWithKey(fileData, key);
return FileEncryptor_ChaCha20_BouncyCastle.encryptFileWithKey(key, fileData);
default:
throw new RuntimeException("Unsupported algorith '" + algorithm + "'!");
}
}

public static void decryptFileWithPassphrase(
final String algorithm,
final String passphrase,
final File inputFile,
final File outputFile,
final String passphrase
final File outputFile
) throws Exception {
switch(StringUtil.trimToEmpty(algorithm).toUpperCase()) {
case "AES256-CBC":
FileEncryptor_AES256_CBC.decryptFileWithPassphrase(inputFile, outputFile, passphrase);
FileEncryptor_AES256_CBC.decryptFileWithPassphrase(passphrase, inputFile, outputFile);
break;
case "AES256-GCM":
FileEncryptor_AES256_GCM.decryptFileWithPassphrase(inputFile, outputFile, passphrase);
FileEncryptor_AES256_GCM.decryptFileWithPassphrase(passphrase, inputFile, outputFile);
break;
case "CHACHA20":
FileEncryptor_ChaCha20.decryptFileWithPassphrase(inputFile, outputFile, passphrase);
FileEncryptor_ChaCha20.decryptFileWithPassphrase(passphrase, inputFile, outputFile);
break;
case "CHACHA20-BC":
FileEncryptor_ChaCha20_BouncyCastle.decryptFileWithPassphrase(inputFile, outputFile, passphrase);
FileEncryptor_ChaCha20_BouncyCastle.decryptFileWithPassphrase(passphrase, inputFile, outputFile);
break;
default:
throw new RuntimeException("Unsupported algorith '" + algorithm + "'!");
Expand All @@ -143,41 +143,41 @@ public static void decryptFileWithPassphrase(

public static byte[] decryptFileWithPassphrase(
final String algorithm,
final byte[] fileData,
final String passphrase
final String passphrase,
final byte[] fileData
) throws Exception {
switch(StringUtil.trimToEmpty(algorithm).toUpperCase()) {
case "AES256-CBC":
return FileEncryptor_AES256_CBC.decryptFileWithPassphrase(fileData, passphrase);
return FileEncryptor_AES256_CBC.decryptFileWithPassphrase(passphrase, fileData);
case "AES256-GCM":
return FileEncryptor_AES256_GCM.decryptFileWithPassphrase(fileData, passphrase);
return FileEncryptor_AES256_GCM.decryptFileWithPassphrase(passphrase, fileData);
case "CHACHA20":
return FileEncryptor_ChaCha20.decryptFileWithPassphrase(fileData, passphrase);
return FileEncryptor_ChaCha20.decryptFileWithPassphrase(passphrase, fileData);
case "CHACHA20-BC":
return FileEncryptor_ChaCha20_BouncyCastle.decryptFileWithPassphrase(fileData, passphrase);
return FileEncryptor_ChaCha20_BouncyCastle.decryptFileWithPassphrase(passphrase, fileData);
default:
throw new RuntimeException("Unsupported algorith '" + algorithm + "'!");
}
}

public static void decryptFileWithKey(
final String algorithm,
final byte[] key,
final File inputFile,
final File outputFile,
final byte[] key
final File outputFile
) throws Exception {
switch(StringUtil.trimToEmpty(algorithm).toUpperCase()) {
case "AES256-CBC":
FileEncryptor_AES256_CBC.decryptFileWithKey(inputFile, outputFile, key);
FileEncryptor_AES256_CBC.decryptFileWithKey(key, inputFile, outputFile);
break;
case "AES256-GCM":
FileEncryptor_AES256_GCM.decryptFileWithKey(inputFile, outputFile, key);
FileEncryptor_AES256_GCM.decryptFileWithKey(key, inputFile, outputFile);
break;
case "CHACHA20":
FileEncryptor_ChaCha20.decryptFileWithKey(inputFile, outputFile, key);
FileEncryptor_ChaCha20.decryptFileWithKey(key, inputFile, outputFile);
break;
case "CHACHA20-BC":
FileEncryptor_ChaCha20_BouncyCastle.decryptFileWithKey(inputFile, outputFile, key);
FileEncryptor_ChaCha20_BouncyCastle.decryptFileWithKey(key, inputFile, outputFile);
break;
default:
throw new RuntimeException("Unsupported algorith '" + algorithm + "'!");
Expand All @@ -186,18 +186,18 @@ public static void decryptFileWithKey(

public static byte[] decryptFileWithKey(
final String algorithm,
final byte[] fileData,
final byte[] key
final byte[] key,
final byte[] fileData
) throws Exception {
switch(StringUtil.trimToEmpty(algorithm).toUpperCase()) {
case "AES256-CBC":
return FileEncryptor_AES256_CBC.decryptFileWithKey(fileData, key);
return FileEncryptor_AES256_CBC.decryptFileWithKey(key, fileData);
case "AES256-GCM":
return FileEncryptor_AES256_GCM.decryptFileWithKey(fileData, key);
return FileEncryptor_AES256_GCM.decryptFileWithKey(key, fileData);
case "CHACHA20":
return FileEncryptor_ChaCha20.decryptFileWithKey(fileData, key);
return FileEncryptor_ChaCha20.decryptFileWithKey(key, fileData);
case "CHACHA20-BC":
return FileEncryptor_ChaCha20_BouncyCastle.decryptFileWithKey(fileData, key);
return FileEncryptor_ChaCha20_BouncyCastle.decryptFileWithKey(key, fileData);
default:
throw new RuntimeException("Unsupported algorith '" + algorithm + "'!");
}
Expand Down
Loading

0 comments on commit 4072588

Please sign in to comment.