Skip to content

Commit

Permalink
Finalize release.
Browse files Browse the repository at this point in the history
  • Loading branch information
Si13n7 committed Jun 24, 2021
1 parent e6b8ada commit dafafbb
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 27 deletions.
55 changes: 37 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,45 @@
<a href="https://www.si13n7.de"><img src="https://img.shields.io/website/https/www.si13n7.de?style=for-the-badge&down_color=critical&down_message=down&label=mirror&up_color=success&up_message=up&logo=data%3Aimage%2Fpng%3Bbase64%2CiVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAEwSURBVDhPxZJNSgNBEIXnCp5AcCO4CmaTRRaKBhdCFkGCCKLgz2Y2RiQgCiqZzmi3CG4COj0X8ApewSt4Ba%2FQ9leZGpyVG8GComtq3qv3qmeS%2Fw9nikHMd5sVn3bqLx7zom1NcW8z%2F6G9CjoPm722rPEv45EJ21vD0O30AvX12IWDvTRsrPXrnjPlUYO0u3McVpZXhch5cnguZ7vVDWfpjRAZgPqc%2BIMEgKQe9Pfr0xn%2FBqZJjAUNQKilp5cC1gHYYz8Usc3OQsTz9HZWK5BMJwFDwrbWbuIXhfhg%2FDpWuE2mK5lEgQtiz4baU14u3V09i5peiipy6qVAxFWtZiflJiq8AAiIZx1CnxpStGmEpEHDZf4r2pUd%2BMjYxomoxJofo4L%2FHqyR57OF6vEvIkm%2BAYRc%2BWd4P97CAAAAAElFTkSuQmCC" title="Visit the developer&apos;s mirror website" alt="Mirror"></a>
</p>


# Roydl.Crypto

The idea was to create a handy way to hash and encrypt data, which can be used in any situation.
The idea was to create a simple way to hash any type of data. So, there are generic extensions for almost any type. A handful algorithms are currently offered, but more will be added over time. Some algorithms are performance optimized and probably more powerful than any other pure C# library of its kind.

## Install:
```julia
$ dotnet add package Roydl.Crypto
```

### Checksum Algorithms:

| Name | Hash Size | Algorithm | Type |
| ---- | ---- | ---- | ---- |
| Adler-32 | 32-bit | Standard | [Cyclic](https://en.wikipedia.org/wiki/Cyclic_code) |
| CRC | 8-bit to 82-bit (no limit for custom) | Choose from [88 presets](https://github.com/Roydl/Crypto/wiki/1.-Checksum-Algorithms) or create your own | [Cyclic](https://en.wikipedia.org/wiki/Cyclic_code) |
| MD5 | 128-bit | Built-in + HMAC keyed-hash support | [Cryptographic](https://en.wikipedia.org/wiki/Cryptographic_hash_function) |
| SHA-1 | 160-bit | Built-in + HMAC keyed-hash support | [Cryptographic](https://en.wikipedia.org/wiki/Cryptographic_hash_function) |
| SHA-2 | 256-bit to 512-bit | Built-in + HMAC keyed-hash support | [Cryptographic](https://en.wikipedia.org/wiki/Cryptographic_hash_function) |
| Name | Bit Width | Algorithm | Type | Hardware Support |
| :---- | ----: | :---- | :---- | :----: |
| Adler-32 | 32-bit | Standard | [Cyclic](https://en.wikipedia.org/wiki/Cyclic_code) | SSE2 _(limited)_ |
| CRC | _from_ 8-bit<br>_to_ 82-bit | [88 presets](https://github.com/Roydl/Crypto/wiki/1.-Checksum-Algorithms) available + customizable | [Cyclic](https://en.wikipedia.org/wiki/Cyclic_code) | iSCSI @ SSE4.2 <br> iSCSI + PKZip @ ARM |
| MD5 | 128-bit | [Built-in](https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.md5?view=net-5.0) + [HMAC](https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.hmacmd5?view=net-5.0) keyed-hash support | [Cryptographic](https://en.wikipedia.org/wiki/Cryptographic_hash_function) | :heavy_multiplication_x: |
| SHA-1 | 160-bit | [Built-in](https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.sha1?view=net-5.0) + [HMAC](https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.hmacsha1?view=net-5.0) keyed-hash support | [Cryptographic](https://en.wikipedia.org/wiki/Cryptographic_hash_function) | :heavy_multiplication_x: |
| SHA-2 | 256-bit<br>384-bit<br>512-bit | [Built-in](https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.sha256?view=net-5.0) + [HMAC](https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.hmacsha256?view=net-5.0) keyed-hash support | [Cryptographic](https://en.wikipedia.org/wiki/Cryptographic_hash_function) | :heavy_multiplication_x: |

### Checksum Performance:

_Especially for Alder and CRC, the performance in software mode should be much better than with any other pure C# library, but similar to libraries that work with C/C++ imports. However, I couldn't find any other library with hardware support, not even with imports. So the performance should be better in some cases._

| Algorithm | Library | Mode | Speed |
| :---- | :----: | :----: | ----: |
| Adler-32 | **This** | Software | **1566,2 MiB/s** |
| Adler-32 | **This** | Hardware | **2099,4 MiB/s** |
| CRC-32 | [Crc32.NET](https://github.com/force-net/Crc32.NET) | Software | 1602,7 MB/s |
| CRC-32 | **This** | Software | **2040,9 MiB/s** |
| CRC-32 | **This** | Hardware | **8393.9 MiB/s** |
| SHA-256 | [Built-in](https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.sha256?view=net-5.0) | Software | 1846,7 MiB/s |

_In the test case, a 64 KiB packet with random bytes is generated, which is sent over and over again within 9 seconds by the function that computes the hash. During this process, it is determined several times how much data could be hashed within 1 second. It seems like 9 seconds is the sweet spot. Increasing this time does not provide more accurate results. However, repetitions offer better results by saving all results, determining the maximum and minimum values and thus identifying fluctuations. The most accurate result seems to be the average of 20 repetitions. You can find the test case [here](https://github.com/Roydl/Crypto/blob/master/test/BenchmarkTests/ChecksumPerformanceTests.cs)._

#### Usage:
### Usage:

The `GetChecksum` extension method retrieves a **string** representation of the computed hash.

The **value** can be almost anything. No matter if it is **bool**, **sbyte**, **byte**, **short**, **ushort**, **char**, **int**, **uint**, **long**, **ulong**, **Half**, **float**, **double**, **decimal**, **Enum**, **IntPtr**, **UIntPtr**, **Vector{T}**, **Vector2**, **Vector3**, **Vector4**, **Matrix3x2**, **Matrix4x4**, **Plane**, **Quaternion**, **Complex**, **BigInteger**, **DateTime**, **DateTimeOffset**, **TimeSpan**, **Guid**, **Rune**, **Stream**, **StreamReader**, **FileInfo**, any **IEnumerable{T}** **byte** sequence, i.e. **Array**, or any **IEnumerable{T}** **char** sequence, i.e. **string**.
_The **value** can be almost anything. No matter if it is **bool**, **sbyte**, **byte**, **short**, **ushort**, **char**, **int**, **uint**, **long**, **ulong**, **Half**, **float**, **double**, **decimal**, **Enum**, **IntPtr**, **UIntPtr**, **Vector{T}**, **Vector2**, **Vector3**, **Vector4**, **Matrix3x2**, **Matrix4x4**, **Plane**, **Quaternion**, **Complex**, **BigInteger**, **DateTime**, **DateTimeOffset**, **TimeSpan**, **Guid**, **Rune**, **Stream**, **StreamReader**, **FileInfo**, any **IEnumerable{T}** **byte** sequence, i.e. **Array**, or any **IEnumerable{T}** **char** sequence, i.e. **string**._

Not every type makes sense, but is supported anyway.

Expand Down Expand Up @@ -76,7 +95,7 @@ An instances provides a computed hash in several variants.

```cs
ReadOnlyMemory<byte> rawHash = instance.RawHash;
BigInteger cipher = instance.HashNumber; // The type depends on the hash size in bits, e.g. CRC-32 is `UInt32`
BigInteger cipher = instance.CipherHash; // The type depends on the hash size in bits, e.g. CRC-32 is `UInt32`
string lowercase = instance.Hash;
string uppercase = instance.ToString(true);
```
Expand All @@ -96,7 +115,7 @@ bool equ = (instance1 == instance2);
bool neq = (instance1 != instance2);
```

#### CRC customization:
### CRC customization:

If you need a different CRC algorithm, you can easily create your own variation.

Expand Down Expand Up @@ -132,14 +151,14 @@ The **value** can be from type **Stream**, **byte[]**, **string**, **FileInfo**,

```cs
var crc = new Crc<uint>(config);
crc.Encrypt(value);
crc.ComputeHash(value);
```

As mentioned earlier, instances offer computed hashes in several variants. It follows the same rules that have already been explained above.

```cs
ReadOnlyMemory<byte> rawHash = crc.RawHash;
uint cipher = crc.HashNumber;
uint cipher = crc.CipherHash;
string lowercase = crc.Hash;
```

Expand All @@ -155,19 +174,19 @@ Check out the [CRC configuration manager](https://github.com/Roydl/Crypto/blob/m
| Rijndael | `128` bit block size; optional: `128`, `192` or `256` bit key size, `cipher` and `padding` modes |


#### Usage:
### Usage:
```cs
byte[] password = new byte[] { /* some bytes */ };
byte[] salt = new byte[] { /* some bytes */ };
using var aes = new Rijndael(password, salt, 1000, SymmetricKeySize.Large);

byte[] encryptedBytes = aes.EncryptBytes(new byte[] { /* some bytes */ });
byte[] encryptedBytes = aes.Encrypt(new byte[] { /* some bytes */ });
byte[] encryptedFile = aes.EncryptFile("C:\\FileToEncrypt.example");
aes.EncryptFile("C:\\FileToEncrypt.example", "C:\\EncryptedFile.example");

aes.EncryptStream(streamToEncrypt, encryptedStream);

byte[] decryptedBytes = aes.DecryptBytes(new byte[] { /* some bytes */ });
byte[] decryptedBytes = aes.Decrypt(new byte[] { /* some bytes */ });
byte[] decryptedFile = aes.DecryptFile("C:\\Some\\File.source");
aes.DecryptFile("C:\\FileToDecrypt.example", "C:\\DecryptedFile.example");

Expand Down
8 changes: 4 additions & 4 deletions src/Checksum/CrcConfig32.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,11 @@ public CrcConfig32(int bitWidth, uint check, uint poly, uint init = default, boo
{
32 => check switch
{
0xe3069283u => 1, // iSCSI: allows hardware mode on `ARM` or `CPU + SSE4.2 support`
0xcbf43926u => 2, // PKZip: allows hardware mode on `ARM`
_ => 0 // Default
0xe3069283u => 1, // `iSCSI` config, which is available for hardware mode on `ARM` and `CPU + SSE4.2`
0xcbf43926u => 2, // `PKZip` config, which is only available for hardware mode on` ARM`
_ => 0 // Default
},
_ => 0 // Default: software mode
_ => 0 // Software mode by default
};

switch (_mode)
Expand Down
2 changes: 1 addition & 1 deletion src/CryptoExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -654,7 +654,7 @@ public static bool TryGetChecksum<TSource>(this TSource source, [NotNullWhen(tru
/// <param name="searchOption">One of the enumeration values that specifies whether the operation should include only the current directory or all subdirectories.</param>
/// <param name="algorithm">The algorithm to use.</param>
/// <param name="result">If successful, a sequence of <see cref="string"/>-based <see cref="KeyValuePair"/>&lt;<see langword="FilePath"/>, <see langword="Checksum"/>&gt; objects provided by an <see cref="IDictionary{TKey, TValue}"/> object that contains the result of hashing the files of the specified <paramref name="dirInfo"/> by the specified <paramref name="algorithm"/>; otherwise, <see langword="default"/>.</param>
/// <remarks></remarks>
/// <remarks>Note that the performance of this function has been optimized and should only be limited by the read speed of the hard disk.</remarks>
/// <returns><see langword="true"/> if the files of the specified <paramref name="dirInfo"/> could be hashed by the specified <paramref name="algorithm"/>; otherwise, <see langword="false"/>.</returns>
public static bool TryGetChecksums(this DirectoryInfo dirInfo, SearchOption searchOption, ChecksumAlgo algorithm, [NotNullWhen(true)] out IDictionary<string, string> result)
{
Expand Down
7 changes: 4 additions & 3 deletions src/CryptoUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public static int CombineHashCodes(object obj1, object obj2) =>

/// <param name="hashes">A sequence of 32-bit signed integers.</param>
/// <inheritdoc cref="CombineHashCodes(int, int)"/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int CombineHashCodes(params int[] hashes)
{
switch (hashes?.Length)
Expand Down Expand Up @@ -72,7 +73,7 @@ public static int CombineHashCodes(params object[] objects)
/// <param name="source">The sequence of bytes to convert.</param>
/// <param name="size">Determines the size of the output string. If the value is greater than 0 but is less than length of <paramref name="source"/>, only the last bytes are converted. If the value is greater than length of <paramref name="source"/>, the result is padded with zeros at the beginning.</param>
/// <param name="uppercase"><see langword="true"/> to convert letters to uppercase; otherwise, <see langword="false"/>.</param>
/// <remarks>Note that this feature is highly performance optimized.</remarks>
/// <remarks>Note that the performance of this function has been extremely optimized.</remarks>
/// <returns>A hexadecimal string that represents the specified sequence of bytes.</returns>
public static string GetString(ReadOnlySpan<byte> source, int size = default, bool uppercase = false)
{
Expand All @@ -89,9 +90,9 @@ public static string GetString(ReadOnlySpan<byte> source, int size = default, bo
Span<char> span = stackalloc char[size];
if (size > len * 2)
span.Fill('0');
for (int i = len, j = size - 1; i > 0; --i)
for (int i = 1, j = size - 1; i <= len; i++)
{
var b = source[i - 1];
var b = source[^i];
span[j] = hex[b & 0xf];
if (--j < 0)
break;
Expand Down
2 changes: 1 addition & 1 deletion src/Roydl.Crypto.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<Company>Roy Schroedel</Company>
<Authors>Roy Schroedel</Authors>
<PackageLicenseFile>LICENSE.txt</PackageLicenseFile>
<Description>Provides a handy and performant way to hash data using Adler32, CRC (8-bit to 82-bit, and customizable without bit restriction), MD5, SHA-1 and SHA-2 (256-bit, 384-bit and 512-bit), including HMAC keyed hashing for some types. Functions for encrypting and decrypting data with Rijndael (128-bit, 192-bit and 256-bit) are also offered.</Description>
<Description>The idea was to create a simple way to hash any type of data. So, there are generic extensions for almost any type. Some algorithms are performance optimized and probably more powerful than any other pure C# library of its kind.</Description>
<PackageProjectUrl>https://github.com/Roydl/Crypto</PackageProjectUrl>
<PackageIcon>LOGO.png</PackageIcon>
<RepositoryUrl>https://github.com/Roydl/Crypto</RepositoryUrl>
Expand Down

0 comments on commit dafafbb

Please sign in to comment.