PQCrypto.Lai 0.1.0

dotnet add package PQCrypto.Lai --version 0.1.0
                    
NuGet\Install-Package PQCrypto.Lai -Version 0.1.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="PQCrypto.Lai" Version="0.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="PQCrypto.Lai" Version="0.1.0" />
                    
Directory.Packages.props
<PackageReference Include="PQCrypto.Lai" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add PQCrypto.Lai --version 0.1.0
                    
#r "nuget: PQCrypto.Lai, 0.1.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#addin nuget:?package=PQCrypto.Lai&version=0.1.0
                    
Install PQCrypto.Lai as a Cake Addin
#tool nuget:?package=PQCrypto.Lai&version=0.1.0
                    
Install PQCrypto.Lai as a Cake Tool

<p align="center"> <img src="https://raw.githubusercontent.com/4211421036/pqcrypto/main/logo.png" alt="PQCrypto Logo" width="200" /> </p>

PQCrypto.Lai

Post-Quantum Lemniscate-AGM Isogeny (LAI) Encryption Library for .NET

A .NET(Standard) library implementing the mathematical primitives and high-level API of the Lemniscate-AGM Isogeny (LAI) encryption scheme. The LAI scheme is a promising post-quantum cryptosystem built on isogenies of elliptic curves over lemniscate lattices. It offers conjectured resistance against quantum-capable adversaries, making it a strong candidate for post-quantum encryption in academic research, prototyping, and security-critical .NET applications.


Table of Contents

  1. Overview

  2. Mathematical Background

    1. Hash-Based Seed Function
    2. Modular Square Root (Tonelli–Shanks)
    3. LAI Transformation T
    4. Binary Exponentiation of T
  3. Features

  4. Installation

    1. Via NuGet
    2. From Source
  5. Usage

    1. Key Generation, Encryption & Decryption (C#)
    2. Decrypting an External JSON Payload
  6. API Reference

  7. Testing

  8. Contributing

  9. License


Overview

Lemniscate-AGM Isogeny (LAI) is an isogeny-based public-key scheme defined over a prime field $\mathbb{F}_p$. Compared to conventional elliptic‐curve cryptography, LAI leverages isogenies of elliptic curves defined over lemniscate lattices. Its security relies on the hardness of computing iterated isogeny walks when a quantum adversary is present.

This library provides:

  • A pure-.NET implementation of all low-level primitives: SHA-256 seed hashing, Tonelli–Shanks modular square root, and the LAI transformation $T$.
  • A high-level API (KeyGen, Encrypt, Decrypt) for message confidentiality.
  • A byte-to-integer block encoder/decoder to enable arbitrary text or binary payload encryption.
  • Comprehensive documentation with direct correspondence to mathematical formulas and pseudocode.

It is designed for researchers, educators, and developers who wish to experiment with or integrate a reference LAI implementation into .NET projects.


Mathematical Background

Below is a concise summary of the key mathematical components. For full details, see the corresponding scientific papers on LAI.

1. Hash-Based Seed Function

Define $H(x, y, s)$ over $\mathbb{F}_p$ as:

$$ H(x,,y,,s) ;=; \bigl(\mathrm{SHA256}\bigl(\text{bytes}(x),|,\text{bytes}(y),|,\text{bytes}(s)\bigr)\bigr)\bmod p, $$

where $| $ denotes byte-concatenation and $\text{bytes}(\cdot)$ is the big-endian representation of each integer.

2. Modular Square Root (Tonelli–Shanks)

To solve $z^2 \equiv a ;(\bmod,p)$ for prime $p$:

  • If $p \equiv 3 \pmod{4}$, then

    $$ z ;=; a^{\frac{p+1}{4}}\bmod p. $$

  • Else, employ the general Tonelli–Shanks algorithm to find $z$ such that $z^2 \equiv a\pmod{p}$, or determine that no square root exists (when $a$ is not a quadratic residue).

3. LAI Transformation $T$

Given:

  • a point $(x,,y)\in \mathbb{F}_p^2$,
  • a constant parameter $a \in \mathbb{F}_p$,
  • an iteration index $s \in \mathbb{Z}$, the LAI step $T((x,y),,s)$ is defined as:

$$ \begin{aligned} h ; &=, H\bigl(x,,y,,s\bigr)\pmod p,\ x' ; &=, \frac{x + a + h}{2}\pmod p,\ y' ; &=, \sqrt{x,y + h}\pmod p\quad (\text{Tonelli–Shanks}).
\end{aligned} $$

Hence

$$ T\bigl((x,y),,s; a,p\bigr) ;=;\bigl(x',,y'\bigr). $$

4. Binary Exponentiation of $T$

To efficiently compute $\displaystyle T^k(P_0)$ (iterating $T$ exactly $k$ times, with increasing seed index at each step), use exponentiation by squaring:

function PowT(P, k):
    result ← P
    base   ← P
    s      ← 1
    while k > 0:
        if (k mod 2 == 1):
            result = T(result, s)
        base   = T(base, s)
        k      = k >> 1
        s      = s + 1
    return result

Features

  1. .NET Standard 2.0-compatible: Library can be consumed by .NET Framework, .NET Core, .NET 5/6/7+, Xamarin, Unity, etc.
  2. Pure-C# Implementation: Relies only on System.Numerics.BigInteger, System.Security.Cryptography, and built-in cryptographic primitives.
  3. Dynamic JSON Decryption: The DecryptAll(dynamic laiData) method can parse and decrypt a JSON payload conforming to the LAI-ciphertext format.
  4. Comprehensive Documentation: All methods carry XML documentation comments linking directly to the mathematical definitions.
  5. Automated CI/CD: Ready to be extended or forked—includes GitHub Actions workflows for building, packing, and publishing to GitHub Packages and NuGet.org.

Installation

Via NuGet.org

dotnet add package PQCrypto.Lai --version 0.1.0

Or in your .csproj:

<PackageReference Include="PQCrypto.Lai" Version="0.1.0" />

Once installed, simply add:

using PQCrypto;

From Source

If you prefer to build locally:

git clone https://github.com/4211421036/pqcrypto.git
cd pqcrypto/laicrypto
dotnet restore
dotnet build --configuration Release
dotnet pack --configuration Release -o nupkg
# You can then push the .nupkg or reference the DLL directly in your project.

Usage

The following examples assume you have installed the PQCrypto.Lai NuGet package into a .NET project.

Key Generation, Encryption & Decryption (C#)

using System;
using System.Numerics;
using PQCrypto;

class Program
{
    static void Main()
    {
        // 1. Define parameters:
        //    p = a large prime (must satisfy p ≡ 3 (mod 4) or general Tonelli–Shanks),
        //    a = curve parameter (any integer < p),
        //    P0 = initial point (x0, y0) ∈ F_p × F_p. For example:
        BigInteger p  = 10007;
        BigInteger a  = 5;
        (BigInteger X, BigInteger Y) P0 = (1, 0);

        // 2. Key Generation:
        //    Produces a random private scalar 'k' and public point 'Q = T^k(P0)'.
        var (k, Q) = LaiCrypto.KeyGen(p, a, P0);
        Console.WriteLine($"Private key: {k}");
        Console.WriteLine($"Public  key: ({Q.X}, {Q.Y})");

        // 3. Plaintext message (integer < p):
        BigInteger message = 2024;
        Console.WriteLine($"Plaintext message: {message}");

        // 4. Encryption:
        //    Returns (C1, C2, r), where C1 = T^r(P0) and C2 = M + T^r(Q).
        var (C1, C2, r) = LaiCrypto.Encrypt(message, Q, p, a, P0);
        Console.WriteLine($"C1: ({C1.X}, {C1.Y})");
        Console.WriteLine($"C2: ({C2.X}, {C2.Y})");
        Console.WriteLine($"Random r: {r}");

        // 5. Decryption:
        //    Recovers M = C2 - T^k(C1) (take x-coordinate).
        BigInteger recovered = LaiCrypto.Decrypt(C1, C2, k, r, a, p);
        Console.WriteLine($"Recovered message: {recovered}");

        if (recovered != message)
            throw new Exception("Decryption failed: mismatch!");
        Console.WriteLine("Round-trip successful. Message matches.");
    }
}

Decrypting an External JSON Payload

If you receive a JSON ciphertext from another source (e.g., Python, Node.js, or a web service), you can parse and decrypt it directly:

using System;
using System.IO;
using System.Text.Json;
using System.Numerics;
using PQCrypto;

class JsonDecryptExample
{
    static void Main()
    {
        // 1. Load a JSON file that contains the LAI ciphertext representation:
        //    {
        //      "p": 10007,
        //      "a": 5,
        //      "P0": [1, 0],
        //      "k": 1234,
        //      "Q": [Xq, Yq],
        //      "blocks": [
        //        { "C1": [x1, y1], "C2": [x2, y2], "r": r1 },
        //        { "C1": [x3, y3], "C2": [x4, y4], "r": r2 },
        //        ...
        //      ]
        //    }
        string json = File.ReadAllText("ciphertext.json");

        // 2. Deserialize into a dynamic object (System.Text.Json):
        var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
        dynamic laiData = JsonSerializer.Deserialize<dynamic>(json, options);

        // 3. Call DecryptAll(...) to obtain the raw plaintext bytes:
        byte[] plaintextBytes = LaiCrypto.DecryptAll(laiData);

        // 4. Convert bytes to UTF-8 string (or any other encoding as needed):
        string recoveredText = System.Text.Encoding.UTF8.GetString(plaintextBytes);
        Console.WriteLine("Decrypted text:");
        Console.WriteLine(recoveredText);
    }
}

API Reference

Below is a summary of the public API methods exposed by the PQCrypto.Lai namespace. Each method includes a brief description and required parameters.

Method Signature Description
static (BigInteger k, (BigInteger X, BigInteger Y) Q) KeyGen( \) Generate a random private key k and compute public point Q = T^k(P0).
(BigInteger p, BigInteger a, (BigInteger X, BigInteger Y) P0) Parameters: p = prime modulus <br> a = transform parameter <br> P0 = base point $(x_0,y_0)$.
static ( (BigInteger X, BigInteger Y) C1, (BigInteger X, BigInteger Y) C2, BigInteger r ) Encrypt( \) Encrypt a single integer message m < p. <br> Returns ciphertext pair (C1,C2) and random nonce r.
( BigInteger m, (BigInteger X, BigInteger Y) Q, BigInteger p, BigInteger a, (BigInteger X, BigInteger Y) P0 ) Parameters: m = integer message <br> Q = public point <br> p = prime <br> a = transform parameter <br> P0 = base point
static BigInteger Decrypt( \) Decrypt a single ciphertext (C1,C2,r) to recover original integer m.
( (BigInteger X, BigInteger Y) C1, (BigInteger X, BigInteger Y) C2, BigInteger k, BigInteger r, BigInteger a, BigInteger p ) Parameters: C1 = first cipher point <br> C2 = second cipher point <br> k = private key <br> r = nonce used at encryption <br> a, p
static byte[] DecryptAll( \) Decrypt all blocks in a JSON-like dynamic object and return the concatenated plaintext bytes.
(dynamic laiData) Parameter: laiData = dynamic object containing p, a, P0, k, Q, blocks[] (where each block has C1[], C2[], r).
static BigInteger H( \) Compute the SHA-256–based seed: H(x, y, s) mod p.
(BigInteger x, BigInteger y, BigInteger s, BigInteger p) Parameters: points x,y and iteration index s, prime modulus p.
static BigInteger? SqrtMod( \) Compute a modular square root of a modulo prime p, using Tonelli–Shanks or shortcut p ≡ 3 (mod 4). Returns null if no solution exists.
(BigInteger a, BigInteger p) Parameters: a = residue, p = prime modulus.
static (BigInteger X, BigInteger Y) T( \) Perform one LAI transform step on a point (x,y) using seed index s.
((BigInteger X, BigInteger Y) point, BigInteger s, BigInteger a, BigInteger p) Parameters: point = $(x,y)$, s = seed index, a = transform parameter, p = prime.
static (BigInteger X, BigInteger Y) PowT( \) Repeatedly apply T exactly exp times starting from seed startS.
((BigInteger X, BigInteger Y) P, BigInteger startS, int exp, BigInteger a, BigInteger p) Parameters: P = initial point, startS = first seed index, exp = number of iterations, a, p

Testing

This library includes a suite of unit tests that verify correctness of:

  • Key generation → Public point consistency
  • Encryption/Decryption → Round-trip accuracy over random messages
  • Tonelli–Shanks → Validation on both $p \equiv 3\pmod{4}$ and general primes
  • Dynamic JSON decryption → Interoperability with payloads produced by Python or Node.js reference implementations

To run tests locally:

cd laicrypto
dotnet test --configuration Release

Contributing

Contributions are welcome! Please follow these steps:

  1. Fork the repository and create a new feature branch:

    git checkout -b feature/YourNewFeature
    
  2. Implement your changes in C# under laicrypto/.

  3. Add corresponding unit tests under laicrypto.Tests/.

  4. Run tests locally to ensure everything passes:

    cd laicrypto
    dotnet test
    
  5. Submit a Pull Request with a clear description of your changes and any relevant benchmarks.

Please adhere to these guidelines:

  • Follow .NET code style: use camelCase for method parameters, PascalCase for public methods, etc.
  • Include XML documentation comments for all public types and methods.
  • Write or update unit tests to cover new functionality or edge cases.
  • Keep external dependencies to a minimum—prefer built-in .NET libraries.

License

This project is licensed under the MIT License. See LICENSE for full details.


For more information or to report issues, please visit the GitHub repository.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
0.1.0 208 6/2/2025