{"id":28759559,"url":"https://github.com/4211421036/pqcrypto","last_synced_at":"2025-06-17T05:07:36.377Z","repository":{"id":296476134,"uuid":"993524886","full_name":"4211421036/pqcrypto","owner":"4211421036","description":"LAI is a promising post-quantum cryptosystem based on isogenies of elliptic curves over lemniscate lattices, offering resistance against quantum-capable adversaries.","archived":false,"fork":false,"pushed_at":"2025-06-06T11:08:59.000Z","size":932,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-06-08T22:11:31.630Z","etag":null,"topics":["cybersecurity","isogenies","lemniscate","post-quantum-cryptography"],"latest_commit_sha":null,"homepage":"https://4211421036.github.io/pqcrypto/","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/4211421036.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-05-31T00:21:26.000Z","updated_at":"2025-06-06T11:09:01.000Z","dependencies_parsed_at":"2025-05-31T11:02:58.999Z","dependency_job_id":"d7339724-2ad6-4ae4-8c6b-1da56406b94f","html_url":"https://github.com/4211421036/pqcrypto","commit_stats":null,"previous_names":["4211421036/pqcrypto"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/4211421036/pqcrypto","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/4211421036%2Fpqcrypto","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/4211421036%2Fpqcrypto/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/4211421036%2Fpqcrypto/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/4211421036%2Fpqcrypto/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/4211421036","download_url":"https://codeload.github.com/4211421036/pqcrypto/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/4211421036%2Fpqcrypto/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":260294463,"owners_count":22987624,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cybersecurity","isogenies","lemniscate","post-quantum-cryptography"],"created_at":"2025-06-17T05:07:35.626Z","updated_at":"2025-06-17T05:07:36.367Z","avatar_url":"https://github.com/4211421036.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# pqcrypto\n\n\u003cimg src=\"https://github.com/4211421036/pqcrypto/blob/main/logo.png\" alt=\"pqcrypto Logo\"/\u003e\n\n\u003cp align=\"center\" style=\"display: flex; justify-content: center; align-items: center; flex-wrap: wrap; gap: 0.5em;\"\u003e\n  \u003ca href=\"https://pypi.org/project/laicrypto/\"\u003e\n    \u003cimg src=\"https://img.shields.io/pypi/v/laicrypto.svg\" alt=\"PyPI version\"/\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://pypi.org/project/laicrypto/\"\u003e\n    \u003cimg src=\"https://img.shields.io/pypi/dm/laicrypto.svg\" alt=\"PyPI downloads\"/\u003e\n  \u003c/a\u003e\n\n  \u003ca href=\"https://www.npmjs.com/package/pqlaicrypto\"\u003e\n    \u003cimg src=\"https://img.shields.io/npm/v/pqlaicrypto.svg\" alt=\"npm version\"/\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://www.npmjs.com/package/pqlaicrypto\"\u003e\n    \u003cimg src=\"https://img.shields.io/npm/dm/pqlaicrypto.svg\" alt=\"npm downloads\"/\u003e\n  \u003c/a\u003e\n\n  \u003ca href=\"https://rubygems.org/gems/laicrypto\"\u003e\n    \u003cimg src=\"https://img.shields.io/gem/v/laicrypto.svg\" alt=\"RubyGems version\"/\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://rubygems.org/gems/laicrypto\"\u003e\n    \u003cimg src=\"https://img.shields.io/gem/dt/laicrypto.svg\" alt=\"RubyGems downloads\"/\u003e\n  \u003c/a\u003e\n\n  \u003ca href=\"https://www.nuget.org/packages/PQCrypto.Lai/\"\u003e\n    \u003cimg src=\"https://img.shields.io/nuget/v/PQCrypto.Lai.svg\" alt=\"NuGet version\"/\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://www.nuget.org/packages/PQCrypto.Lai/\"\u003e\n    \u003cimg src=\"https://img.shields.io/nuget/dt/PQCrypto.Lai.svg\" alt=\"NuGet downloads\"/\u003e\n  \u003c/a\u003e\n\n\u003c/p\u003e\n\n**Post-Quantum Lemniscate-AGM Isogeny (LAI) Encryption**\n\nA multi-language reference implementation of the Lemniscate-AGM Isogeny (LAI) encryption scheme.  \nLAI is a promising post-quantum cryptosystem based on isogenies of elliptic curves over lemniscate lattices, offering conjectured resistance against quantum-capable adversaries.\n\n---\n\n## Table of Contents\n\n1. [Project Overview](#project-overview)\n2. [Mathematical Formulation](#mathematical-formulation)\n3. [Features](#features)\n4. [Releases \u0026 Package Managers](#releases--package-managers)  \n   4.1. [Python (PyPI)](#python-pypi)  \n   4.2. [JavaScript (npm)](#javascript-npm)  \n   4.3. [Ruby (RubyGems)](#ruby-rubygems)  \n   4.4. [.NET (NuGet)](#net-nuget)  \n   4.5. [Java (Maven)](#java)  \n5. [Usage Examples](#usage-examples)  \n   5.1. [Python](#python)  \n   5.2. [JavaScript](#javascripts)  \n   5.3. [Ruby](#ruby)  \n   5.4. [.NET (C#)](#net-c)  \n   5.5. [Java](#java)  \n6. [API Reference](#api-reference)  \n7. [Testing](#testing)  \n8. [Contributing \u0026 Development](#contributing--development)  \n9. [License](#license)\n\n---\n\n## Project Overview\n\nThis library implements all core mathematical primitives and high-level APIs for LAI:\n\n- **Hash-Based Seed Function**  \n  $$\\( H(x, y, s) = \\mathrm{SHA256}\\bigl(x\\,\\|\\,y\\,\\|\\,s\\bigr) \\bmod p \\)$$\n- **Modular Square Root** via Tonelli–Shanks (with fast branch if $$\\(p \\equiv 3 \\pmod 4\\)$$).\n- **LAI Transformation**\n\n  $$\\[\nT\\bigl((x,y),\\,s;\\,a,\\,p\\bigr)\n\\;=\\;\n\\Bigl(\\,\n  x' \\;=\\; \\tfrac{x + a + h}{2} \\bmod p,\\;\\;\n  y' \\;=\\; \\sqrt{x\\,y + h}\\bmod p\n\\Bigr)\n\\]\n$$\n\n  where $$\\(h = H(x,y,s)\\)$$.\n- **Binary Exponentiation** of $$\\(T\\)$$ to compute $$\\(T^k(P_0)\\)$$ in $$\\(O(\\log k)\\$$) time.\n- **Key Generation, Encryption, and Decryption** routines for integer messages $$\\(0 \\le m \u003c p\\)$$.\n- **Bulk JSON Decryption**: decrypt an entire JSON payload into raw bytes (e.g., to reconstruct a file or UTF-8 text).\n\nAll language‐specific wrappers expose identical API semantics under the hood. This makes pqcrypto ideal for cross-platform experiments, research, and educational purposes.\n\n---\n\n## Mathematical Formulation\n\n### 1. Hash-Based Seed Function\n\nFor $$\\(x, y, s \\in \\mathbb{Z}_p\\)$$, define:\n\n$$\n\\[\nH(x, y, s) \\;=\\; \\mathrm{SHA256}\\bigl(\\text{bytes}(x)\\,\\|\\,\\text{bytes}(y)\\,\\|\\,\\text{bytes}(s)\\bigr)\\;\\bmod\\;p,\n\\]\n$$\n\nwhere $$“\\(\\|\\)”$$ denotes concatenation of the big-endian byte representations.\n\n### 2. Modular Square Root (Tonelli–Shanks)\n\nSolve $$\\(z^2 \\equiv a \\pmod p\\) for prime \\(p\\)$$:\n\n- If $$\\(p \\equiv 3 \\pmod 4\\)$$:\n\n$$\n  \\[\n    z = a^{\\frac{p+1}{4}} \\bmod p.\n  \\]\n$$\n\n- Otherwise: apply the general Tonelli–Shanks algorithm in $$\\(O(\\log^2 p)\\)$$ time.\n\n### 3. LAI Transformation $$\\(T\\)$$\n\nGiven $$\\((x,y)\\in\\mathbb{F}_p^2\\)$$, parameter $$\\(a\\)$$, and seed index $$\\(s\\)$$, define\n\n$$\n\\begin{cases}\n  h = H(x,\\,y,\\,s),\\[6pt]\n  x' = \\dfrac{x + a + h}{2}\\bmod p,\\[6pt]\n  y' = \\sqrt{x\\,y + h}\\;\\bmod p.\n\\end{cases}\n$$\n\nThus $$\\(\\;T\\bigl((x,y),s;a,p\\bigr) = (\\,x',\\,y'\\,)\\)$$.\n\n### 4. Binary Exponentiation of $$\\(T\\)$$\n\nTo compute $$\\(T^k(P_0)\\)$$ efficiently:\n\n```\n\nfunction pow_T(P, k):\n   result ← P\n   base   ← P\n   s      ← 1\n   while k \u003e 0:\n      if (k mod 2) == 1:\n         result ← T(result, s)\n         base ← T(base, s)\n         k    ← k \u003e\u003e 1\n         s    ← s + 1\n   return result\n\n```\n\n### 5. Algorithmic API\n\n**Key Generation**  \n```\n\nfunction keygen(p, a, P0):\n   k ← random integer in [1, p−1]\n   Q ← pow_T(P0, k)\n   return (k, Q)\n\n```\n\n**Encryption**  \n```\n\nfunction encrypt(m, Q, p, a, P0):\n   r  ← random integer in [1, p−1]\n   C1 ← pow_T(P0, r)\n   Sr ← pow_T(Q, r)\n   M  ← (m mod p, 0)\n   C2 ← ((M.x + Sr.x) mod p, (M.y + Sr.y) mod p)\n   return (C1, C2)\n\n```\n\n**Decryption**  \n```\n\nfunction decrypt(C1, C2, k, a, p):\n   S   ← pow_T(C1, k)\n   M.x ← (C2.x − S.x) mod p\n   return M.x\n\n```\n\n**Bulk Decryption (JSON)**  \n```\n\nfunction decryptAll(jsonPayload):\n   parse p, a, P0, k, blocks[]\n   for each block in blocks:\n      (x1,y1) = block.C1\n      (x2,y2) = block.C2\n      r       = block.r\n      M_int   = decrypt((x1,y1),(x2,y2),k,r,a,p)\n      convert M_int into fixed-length big-endian B-byte chunk\n      append to output byte buffer\n   return outputBuffer\n\n````\n\n---\n\n## Features\n\n1. **Pure Implementations** (no native code)  \n   - Python: only uses `hashlib`, `secrets` (stdlib).  \n   - JavaScript: pure JS/BigInt.  \n   - Ruby: pure Ruby + `openssl`.  \n   - C#: uses `System.Numerics.BigInteger` (no external C/C++).  \n   - Java: uses `java.math.BigInteger` + Jackson for JSON.\n\n2. **Mathematically Annotated**  \n   Every function corresponds exactly to the paper’s formulas.\n\n3. **Modular Design**  \n   Separation of low‐level primitives (`H`, `sqrt_mod`, `T`) from high‐level API (`keygen`, `encrypt`, `decrypt`).\n\n4. **General \u0026 Optimized**  \n   - Fast branch for $$\\(p\\equiv3\\pmod4\\)$$.  \n   - Full Tonelli–Shanks fallback for any odd prime.\n\n5. **Bulk JSON Decryption**  \n   Produce or consume large ciphertext payloads (e.g., encrypted files, JavaScript code, JSON blobs).\n\n6. **CI/CD Ready**  \n   - Python: auto‐publish to PyPI via GitHub Actions.  \n   - JS: auto‐publish to npm.  \n   - Ruby: auto‐publish to RubyGems.  \n   - C#: auto‐publish to NuGet \u0026 GitHub Packages.  \n   - Java: auto‐publish to GitHub Packages (Maven).\n\n---\n\n## Releases \u0026 Package Managers\n\n### Python (PyPI)\n\n```bash\npip install laicrypto\n````\n\n### JavaScript (npm)\n\n```bash\nnpm install pqlaicrypto\n```\n\n### Ruby (RubyGems)\n\n```bash\ngem install laicrypto\n```\n\n### .NET (NuGet)\n\n```xml\n\u003cPackageReference Include=\"PQCrypto.Lai\" Version=\"0.1.0\" /\u003e\n```\n\n### Java (Maven Central / GitHub Packages)\n\n```xml\n\u003cdependency\u003e\n  \u003cgroupId\u003ecom.pelajaran.pqcrypto\u003c/groupId\u003e\n  \u003cartifactId\u003elaicrypto\u003c/artifactId\u003e\n  \u003cversion\u003e0.1.0\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n---\n\n## Usage Examples\n\nBelow are minimal “hello, world”-style code snippets for each language wrapper.\n\n### Python\n\n```python\nimport math\nfrom pqcrypto import keygen, encrypt, decrypt\n\n# 1. Setup parameters\np = 10007\na = 5\nP0 = (1, 0)\n\n# 2. Generate keypair\nprivate_k, public_Q = keygen(p, a, P0)\nprint(\"Private k:\", private_k)\nprint(\"Public  Q:\", public_Q)\n\n# 3. Encrypt integer m\nmessage = 2024\nC1, C2 = encrypt(message, public_Q, p, a, P0)\nprint(\"C1:\", C1, \" C2:\", C2)\n\n# 4. Decrypt using private_k\nrecovered = decrypt(C1, C2, private_k, a, p)\nprint(\"Recovered:\", recovered)\nassert recovered == message\n```\n\nIf you need to encrypt an entire text/file, convert it to integer blocks via\n`int.from_bytes(...)`, then call `encrypt(...)` on each block. See the\n[Python demo](#python) in this README for details.\n\n### JavaScripts\n\n```js\n// Install: npm install pqlaicrypto\n\nconst { keygen, encrypt, decrypt } = require(\"pqlaicrypto\");\n\nconst p = 10007n;\nconst a = 5n;\nconst P0 = [1n, 0n];\n\n// 1. Generate keypair\nconst { k, Q } = keygen(p, a, P0);\nconsole.log(\"Private k:\", k.toString());\nconsole.log(\"Public  Q:\", Q);\n\n// 2. Encrypt a small integer\nconst m = 2024n;\nconst { C1, C2, r } = encrypt(m, Q, k, p, a, P0);\nconsole.log(\"C1:\", C1, \"C2:\", C2, \"r:\", r.toString());\n\n// 3. Decrypt\nconst recovered = decrypt(C1, C2, k, r, a, p);\nconsole.log(\"Recovered:\", recovered.toString());\n```\n\nUse `BigInt`-aware file/block conversions to encrypt larger messages or files.\n\n### Ruby\n\n```ruby\n# Install: gem install laicrypto\nrequire \"laicrypto\"\n\np  = 10007\na  = 5\nP0 = [1, 0]\n\n# 1. Generate keypair\nk, Q = LAI.keygen(p, a, P0)\nputs \"Private k: #{k}\"\nputs \"Public  Q: #{Q.inspect}\"\n\n# 2. Encrypt integer\nmessage = 2024\nC1, C2, r = LAI.encrypt(message, Q, k, p, a, P0)\nputs \"C1: #{C1.inspect}  C2: #{C2.inspect}  r: #{r}\"\n\n# 3. Decrypt\nrecovered = LAI.decrypt(C1, C2, k, r, a, p)\nputs \"Recovered: #{recovered}\"\n```\n\nSimilar to Python, convert larger text to integer blocks using `String#bytes`\nand `Integer()`.\n\n### .NET (C#)\n\n```csharp\n// Install via NuGet: \n//   \u003cPackageReference Include=\"PQCrypto.Lai\" Version=\"0.1.0\" /\u003e\n\nusing System;\nusing System.Numerics;\nusing PQCrypto; // namespace containing LaiCrypto\n\nclass Demo {\n    static void Main(string[] args) {\n        // 1. Setup parameters\n        BigInteger p = 10007;\n        BigInteger a = 5;\n        LaiCrypto.Point P0 = new LaiCrypto.Point(1, 0);\n\n        // 2. Generate keypair\n        var kp = LaiCrypto.KeyGen(p, a, P0);\n        Console.WriteLine($\"Private k: {kp.k}\");\n        Console.WriteLine($\"Public  Q: ({kp.Q.x}, {kp.Q.y})\");\n\n        // 3. Encrypt integer\n        BigInteger message = 2024;\n        var ct = LaiCrypto.Encrypt(message, kp.Q, p, a, P0);\n        Console.WriteLine($\"C1: ({ct.C1.x}, {ct.C1.y})  C2: ({ct.C2.x}, {ct.C2.y})  r: {ct.r}\");\n\n        // 4. Decrypt\n        BigInteger recovered = LaiCrypto.Decrypt(ct.C1, ct.C2, kp.k, ct.r, a, p);\n        Console.WriteLine($\"Recovered: {recovered}\");\n        if (recovered != message) throw new Exception(\"Decryption mismatch!\");\n    }\n}\n```\n\nTo decrypt a JSON payload:\n\n```csharp\nusing System.IO;\nusing Newtonsoft.Json.Linq; // or System.Text.Json\n\nvar json = File.ReadAllText(\"ciphertext.json\");\nvar jNode = JObject.Parse(json);\nbyte[] plaintextBytes = LaiCrypto.DecryptAll(jNode);\nstring plaintext = System.Text.Encoding.UTF8.GetString(plaintextBytes);\n```\n\n### Java\n\n```xml\n\u003c!-- In your pom.xml --\u003e\n\u003cdependency\u003e\n  \u003cgroupId\u003ecom.pelajaran.pqcrypto\u003c/groupId\u003e\n  \u003cartifactId\u003elaicrypto\u003c/artifactId\u003e\n  \u003cversion\u003e0.1.0\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n```java\nimport com.pelajaran.pqcrypto.LaiCrypto;\nimport com.pelajaran.pqcrypto.LaiCrypto.Point;\nimport com.pelajaran.pqcrypto.LaiCrypto.KeyPair;\nimport com.pelajaran.pqcrypto.LaiCrypto.Ciphertext;\n\nimport java.math.BigInteger;\n\npublic class LAIDemo {\n    public static void main(String[] args) throws Exception {\n        // 1. Setup\n        BigInteger p = BigInteger.valueOf(10007);\n        BigInteger a = BigInteger.valueOf(5);\n        Point P0 = new Point(BigInteger.ONE, BigInteger.ZERO);\n\n        // 2. Generate key pair\n        KeyPair kp = LaiCrypto.keyGen(p, a, P0);\n        System.out.println(\"Private k: \" + kp.k);\n        System.out.println(\"Public  Q: (\" + kp.Q.x + \", \" + kp.Q.y + \")\");\n\n        // 3. Encrypt integer\n        BigInteger message = BigInteger.valueOf(2024);\n        Ciphertext ct = LaiCrypto.encrypt(message, kp.Q, p, a, P0);\n        System.out.println(\"C1: (\" + ct.C1.x + \", \" + ct.C1.y + \")\");\n        System.out.println(\"C2: (\" + ct.C2.x + \", \" + ct.C2.y + \")\");\n        System.out.println(\"r:  \" + ct.r);\n\n        // 4. Decrypt\n        BigInteger recovered = LaiCrypto.decrypt(ct.C1, ct.C2, kp.k, ct.r, a, p);\n        System.out.println(\"Recovered: \" + recovered);\n    }\n}\n```\n\nTo decrypt a JSON payload in Java:\n\n```java\nimport com.fasterxml.jackson.databind.ObjectMapper;\nimport com.fasterxml.jackson.databind.JsonNode;\n\n// ...\nObjectMapper mapper = new ObjectMapper();\nJsonNode root = mapper.readTree(new File(\"ciphertext.json\"));\nbyte[] plaintextBytes = LaiCrypto.decryptAll(root);\nString plaintext = new String(plaintextBytes, StandardCharsets.UTF_8);\n```\n\n---\n\n## API Reference\n\n| Function                                                                                                     | Description                                                                                    |\n| ------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------- |\n| `H(x: BigInt, y: BigInt, s: BigInt, p: BigInt) → BigInt`                                                     | SHA-256(x \\| y \\| s) mod p.                                                                    |\n| `sqrt_mod(a: BigInt, p: BigInt) → BigInt or null`                                                            | Compute $\\sqrt{a} \\bmod p$. Returns null if no root exists.                                    |\n| `T(point: (BigInt,BigInt), s: BigInt, a: BigInt, p: BigInt) → (BigInt,BigInt)`                               | One LAI transform step.                                                                        |\n| `pow_T(P, startS: BigInt, exp: BigInt, a: BigInt, p: BigInt) → (BigInt,BigInt)`                              | Compute $T^{\\text{exp}}(P)$ by exponentiation by squaring.                                     |\n| `keygen(p: BigInt, a: BigInt, P0: (BigInt,BigInt)) → (k: BigInt, Q: (BigInt,BigInt))`                        | Generate a random private key k and public point Q = Tᵏ(P₀).                                   |\n| `encrypt(m: BigInt, Q: (BigInt,BigInt), k: BigInt, p: BigInt, a: BigInt, P0: (BigInt,BigInt)) → (C1, C2, r)` | Encrypt integer m (\u003c p) yielding C1, C2, and randomness r.                                     |\n| `decrypt(C1: (BigInt,BigInt), C2: (BigInt,BigInt), k: BigInt, r: BigInt, a: BigInt, p: BigInt) → BigInt`     | Decrypt one block, returning the original integer m.                                           |\n| `decryptAll(jsonPayload) → byte[]`                                                                           | Read entire JSON ciphertext payload (array of blocks) and return concatenated plaintext bytes. |\n\n---\n\n## Testing\n\nEach language wrapper includes its own test suite:\n\n* **Python**:\n\n  ```bash\n  pytest --disable-warnings -q\n  ```\n\n* **JavaScript**:\n\n  ```bash\n  npm test\n  ```\n\n* **Ruby**:\n\n  ```bash\n  bundle exec rspec\n  ```\n\n* **.NET (C#)**:\n\n  ```bash\n  dotnet test\n  ```\n\n* **Java (Maven)**:\n\n  ```bash\n  mvn test\n  ```\n\nMake sure all tests pass locally before opening a pull request.\n\n---\n\n## Contributing \u0026 Development\n\n1. **Fork the repository**\n2. **Create a feature branch**\n\n   ```bash\n   git checkout -b feature/your_feature\n   ```\n3. **Implement changes**\n\n   * Add or fix primitives/pseudo-code as needed.\n   * Add unit tests for any new functionality.\n4. **Run tests** in all supported languages.\n5. **Commit \u0026 push**, then open a pull request.\n\nPlease follow PEP 8 style in Python, StandardJS in JavaScript, Ruby Style Guide, C# coding conventions, and Java conventions. Include thorough documentation for any new API.\n\n---\n\n## License\n\nThis project is licensed under the [MIT License](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F4211421036%2Fpqcrypto","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F4211421036%2Fpqcrypto","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F4211421036%2Fpqcrypto/lists"}