Skip to content

Commit

Permalink
Bump package version to 1.1.1 and update CHANGELOG.md; add GitHub Act…
Browse files Browse the repository at this point in the history
…ions workflow for .NET build and test
  • Loading branch information
asagynbaev committed Jan 2, 2025
1 parent bb5feed commit b51aeef
Show file tree
Hide file tree
Showing 7 changed files with 171 additions and 29 deletions.
31 changes: 31 additions & 0 deletions .github/workflows/dotnet.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: .NET Build and Test

on:
push:
branches:
- main
pull_request:
branches:
- main

jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v2

- name: Set up .NET SDK
uses: actions/setup-dotnet@v1
with:
dotnet-version: '8.0'

- name: Restore dependencies
run: dotnet restore

- name: Build the project
run: dotnet build --configuration Release

- name: Run tests
run: dotnet test --configuration Release --no-build --verbosity normal
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# Changelog

## [Unreleased]
## [1.1.1] - 2025-01-01

### Added
- New method for range proofs (`ProveRange` and `VerifyRange`).
- Support for time-based proofs (`ProveTimestamp` and `VerifyTimestamp`).
- Support for proving set membership (`ProveSetMembership` and `VerifySetMembership`).

### Changed
- Updated HMAC implementation to use more secure random salts.
- Refined HMAC implementation to retrieve the secret key from environment variables for enhanced security and flexibility.

### Fixed
- Bug in age verification logic that caused incorrect validation for dates close to the required age.
Expand Down
60 changes: 50 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,58 @@

- **Proof of Age**: Prove that your age is above a certain threshold without revealing your actual birthdate.
- **Proof of Balance**: Prove that you have sufficient balance to make a transaction without revealing your full balance.
- **Proof of Membership**: Prove that a given value belongs to a set of valid values (e.g., proving you belong to a specific group).
- **Proof of Range**: Prove that a value lies within a specified range without revealing the exact value.
- **Proof of Time Condition**: Prove that an event occurred before or after a specified date without revealing the event date.
- **Secure Hashing**: Uses SHA-256 hashing combined with a random salt to ensure secure and non-reversible proofs.


## Installation

You can install **ZkpSharp** via NuGet. Run the following command in your project directory:

```bash
dotnet add package ZkpSharp
```

## Setup

Before using the ZkpSharp library, you need to configure a secret key for HMAC (SHA-256) hashing. This key is required for generating and verifying proofs.

### Setting Up the HMAC Key in Code

Instead of using environment variables, you can pass the HMAC secret key directly when creating the ProofProvider. The key should be a 256-bit key (32 bytes) encoded in Base64.

Here’s an example of how to configure the HMAC key directly in your application:

```csharp
using ZkpSharp;
using ZkpSharp.Security;
using System;

class Program
{
static void Main()
{
// Example base64-encoded HMAC secret key (256 bits / 32 bytes)
string hmacSecretKeyBase64 = "your-base64-encoded-key-here";

// Create an instance of ProofProvider with the provided HMAC key
var proofProvider = new ProofProvider(hmacSecretKeyBase64);

var zkp = new ZKP(proofProvider);
var dateOfBirth = new DateTime(2000, 1, 1); // The user's date of birth
// Generate proof of age
var (proof, salt) = zkp.ProveAge(dateOfBirth);

// Verify the proof of age
bool isValid = zkp.VerifyAge(proof, dateOfBirth, salt);
Console.WriteLine($"Age proof valid: {isValid}");
}
}
```

## Usage

### Proof of Age
Expand Down Expand Up @@ -70,26 +113,23 @@ class Program
}
}
```

## Contributing

We welcome contributions! To contribute:
1. Fork the repository.
2. Create a new branch for your changes (git checkout -b feature/your-feature).
3. Commit your changes (git commit -m 'Add new feature').
4. Push to your branch (git push origin feature/your-feature).
5. Create a pull request.

1. Fork the repository.
2. Create a new branch for your changes (`git checkout -b feature/your-feature`).
3. Commit your changes (`git commit -m 'Add new feature'`).
4. Push to your branch (`git push origin feature/your-feature`).
5. Create a pull request.

Please ensure that your code passes all tests and adheres to the code style of the project.

## License

This project is licensed under the MIT License - see the LICENSE file for details.

## Roadmap
• Add more proof types (e.g., Proof of Identity, Proof of Transaction History).
• Improve performance and scalability for large datasets.
• Enhance security features (e.g., multi-factor authentication for proofs).

## Contact

For questions, issues, or suggestions, feel free to open an issue or contact Azimbek Sagynbaev at [sagynbaev6@gmail.com].
19 changes: 11 additions & 8 deletions ZkpSharp.Tests/ZKPTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public class ZKPTests
[Fact]
public void TestProveAndVerifyAge_ValidAge_ShouldPass()
{
var proofProvider = new ProofProvider();
var proofProvider = new ProofProvider("hmacSecretKeyBase64");
var zkp = new ZKP(proofProvider);
var dateOfBirth = new DateTime(2000, 1, 1); // Age 25
var (proof, salt) = zkp.ProveAge(dateOfBirth);
Expand All @@ -21,7 +21,7 @@ public void TestProveAndVerifyAge_ValidAge_ShouldPass()
[Fact]
public void TestProveAndVerifyAge_InsufficientAge_ShouldFail()
{
var proofProvider = new ProofProvider();
var proofProvider = new ProofProvider("hmacSecretKeyBase64");
var zkp = new ZKP(proofProvider);
var dateOfBirth = new DateTime(2010, 1, 1); // Age 15

Expand All @@ -32,7 +32,7 @@ public void TestProveAndVerifyAge_InsufficientAge_ShouldFail()
[Fact]
public void TestProveAndVerifyBalance_ValidBalance_ShouldPass()
{
var proofProvider = new ProofProvider();
var proofProvider = new ProofProvider("hmacSecretKeyBase64");
var zkp = new ZKP(proofProvider);
double userBalance = 1000.0;
double requestedAmount = 500.0;
Expand All @@ -46,7 +46,7 @@ public void TestProveAndVerifyBalance_ValidBalance_ShouldPass()
[Fact]
public void TestProveAndVerifyBalance_InsufficientBalance_ShouldFail()
{
var proofProvider = new ProofProvider();
var proofProvider = new ProofProvider("hmacSecretKeyBase64");
var zkp = new ZKP(proofProvider);
double userBalance = 300.0;
double requestedAmount = 500.0;
Expand All @@ -59,7 +59,7 @@ public void TestProveAndVerifyBalance_InsufficientBalance_ShouldFail()
[Fact]
public void TestBalanceVerificationWithSalt_ValidBalance_ShouldPass()
{
var proofProvider = new ProofProvider();
var proofProvider = new ProofProvider("hmacSecretKeyBase64");
var zkp = new ZKP(proofProvider);
double userBalance = 1000.0;
double requestedAmount = 500.0;
Expand All @@ -71,7 +71,7 @@ public void TestBalanceVerificationWithSalt_ValidBalance_ShouldPass()
[Fact]
public void TestBalanceVerificationWithSalt_InsufficientBalance_ShouldFail()
{
var proofProvider = new ProofProvider();
var proofProvider = new ProofProvider("hmacSecretKeyBase64");
var zkp = new ZKP(proofProvider);
double userBalance = 100.0;
double requestedAmount = 150.0;
Expand All @@ -83,7 +83,7 @@ public void TestBalanceVerificationWithSalt_InsufficientBalance_ShouldFail()
[Fact]
public void TestProveAndVerifyAge_InvalidSalt_ShouldFail()
{
var proofProvider = new ProofProvider();
var proofProvider = new ProofProvider("hmacSecretKeyBase64");
var zkp = new ZKP(proofProvider);
var dateOfBirth = new DateTime(2000, 1, 1); // Возраст 25 лет
var (proof, salt) = zkp.ProveAge(dateOfBirth);
Expand All @@ -96,7 +96,7 @@ public void TestProveAndVerifyAge_InvalidSalt_ShouldFail()
[Fact]
public void TestBalanceVerificationWithSalt_InvalidSalt_ShouldFail()
{
var proofProvider = new ProofProvider();
var proofProvider = new ProofProvider("hmacSecretKeyBase64");
var zkp = new ZKP(proofProvider);
double userBalance = 1000.0;
double requestedAmount = 500.0;
Expand All @@ -105,5 +105,8 @@ public void TestBalanceVerificationWithSalt_InvalidSalt_ShouldFail()
string incorrectSalt = Guid.NewGuid().ToString();
Assert.False(zkp.VerifyBalance(proof, requestedAmount, incorrectSalt, userBalance), "Proof should fail due to incorrect salt");
}

// TODO: Add more tests for:
// ProveRange, VerifyRange, ProveTimestamp, VerifyTimestamp, ProveSetMembership, VerifySetMembership.
}
}
74 changes: 74 additions & 0 deletions ZkpSharp/Core/ZKP.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,79 @@ public bool VerifyBalance(string proof, double requestedAmount, string salt, dou
string calculatedProof = _proofProvider.GenerateHMAC(balance.ToString() + salt);
return _proofProvider.SecureEqual(calculatedProof, proof) && balance >= requestedAmount;
}

// Proof of Membership
public string ProveMembership(string value, string[] validValues)
{
string salt = _proofProvider.GenerateSalt();
var validValueHash = validValues.Select(v => _proofProvider.GenerateHMAC(v)).ToArray();

foreach (var hash in validValueHash)
{
if (_proofProvider.SecureEqual(_proofProvider.GenerateHMAC(value + salt), hash))
{
return salt;
}
}

throw new ArgumentException("Value does not belong to the set.");
}

public bool VerifyMembership(string value, string salt, string[] validValues)
{
var validValueHash = validValues.Select(v => _proofProvider.GenerateHMAC(v)).ToArray();
string proof = _proofProvider.GenerateHMAC(value + salt);

return validValueHash.Contains(proof);
}

// Proof of Range
public string ProveRange(double value, double minValue, double maxValue)
{
if (value < minValue || value > maxValue)
{
throw new ArgumentException("Value out of range.");
}

string salt = _proofProvider.GenerateSalt();
string proof = _proofProvider.GenerateHMAC(value.ToString() + salt);
return proof;
}

public bool VerifyRange(string proof, double minValue, double maxValue, double value)
{
if (value < minValue || value > maxValue)
{
return false;
}

string calculatedProof = _proofProvider.GenerateHMAC(value.ToString() + _proofProvider.GenerateSalt());
return _proofProvider.SecureEqual(proof, calculatedProof);
}


// Proof of Time Condition
public string ProveTimeCondition(DateTime eventDate, DateTime conditionDate)
{
if (eventDate < conditionDate)
{
throw new ArgumentException("Event does not meet the time condition.");
}

string salt = _proofProvider.GenerateSalt();
string proof = _proofProvider.GenerateHMAC(eventDate.ToString("yyyy-MM-dd") + salt);
return proof;
}

public bool VerifyTimeCondition(string proof, DateTime eventDate, DateTime conditionDate, string salt)
{
if (eventDate < conditionDate)
{
return false;
}

string calculatedProof = _proofProvider.GenerateHMAC(eventDate.ToString("yyyy-MM-dd") + salt);
return _proofProvider.SecureEqual(proof, calculatedProof);
}
}
}
10 changes: 2 additions & 8 deletions ZkpSharp/Security/ProofProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ public class ProofProvider : IProofProvider
{
private readonly byte[] _hmacKey;

public ProofProvider()
public ProofProvider(string hmacSecretKeyBase64)
{
_hmacKey = LoadHmacKey();
_hmacKey = Convert.FromBase64String(hmacSecretKeyBase64);
}

public string GenerateSalt()
Expand Down Expand Up @@ -50,11 +50,5 @@ public bool SecureEqual(string a, string b)

return diff == 0;
}

private byte[] LoadHmacKey()
{
// Load HMAC key from secure storage
return new byte[32]; // Here we just return a dummy key
}
}
}
2 changes: 1 addition & 1 deletion ZkpSharp/ZkpSharp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PackageVersion>1.1.0</PackageVersion>
<PackageVersion>1.1.1</PackageVersion>
<PackageReadmeFile>README.md</PackageReadmeFile>
</PropertyGroup>

Expand Down

0 comments on commit b51aeef

Please sign in to comment.