{"_id":"@cypherlaboratory/alicesring-sag","_rev":"2-547e1e49e0910683c0e1e2a76f867d9b","name":"@cypherlaboratory/alicesring-sag","dist-tags":{"latest":"0.1.2"},"versions":{"0.1.0":{"name":"@cypherlaboratory/alicesring-sag","version":"0.1.0","description":"A TypeScript implementation of SAG ring signatures.","main":"dist/src/index.js","module":"dist/src/index.js","types":"dist/src/index.d.ts","scripts":{"build":"npm run fmt && tsc","test":"jest","lint":"eslint .","lint:fix":"eslint . --fix","prettier":"prettier --check .","prettier:fix":"prettier --write .","fmt:check":"npm run prettier && npm run lint","fmt":"npm run prettier:fix && npm run fmt:check"},"author":{"name":"Elli610 && LeJamon && maximedgr"},"license":"MIT","dependencies":{"@noble/hashes":"^1.3.2","ts-node":"^10.9.1"},"devDependencies":{"@types/jest":"^29.5.7","@types/node":"^20.8.7","@typescript-eslint/eslint-plugin":"^5.61.0","@typescript-eslint/parser":"^5.61.0","eslint":"^8.44.0","ts-jest":"^29.1.1","jest":"^29.7.0","prettier":"^3.0.0"},"_id":"@cypherlaboratory/alicesring-sag@0.1.0","gitHead":"37fdb39317a83d46e02c842b7f0c5f4a68afdcdb","_nodeVersion":"20.11.1","_npmVersion":"10.2.4","dist":{"integrity":"sha512-6Cb3wlYoK2utmBoCaEqLEOz+CwFqG+CGVeji4goFXWPjajAsuETnwFXnCQOihpaba5r7EucyM98NwHfrGgFG+Q==","shasum":"45e0451cbe3c88b904c1b3dc0cce9ba07abb0749","tarball":"https://registry.npmjs.org/@cypherlaboratory/alicesring-sag/-/alicesring-sag-0.1.0.tgz","fileCount":68,"unpackedSize":1534477,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCa42j4QRZOCHuJ34JZPWejXMecBmnTnPeCD/AK79gp6AIgB4p5r1iGew8O/mu47kzx5Tx8TjVIFG4N44bW8nulRb4="}]},"_npmUser":{"name":"cypherlaboratory","email":"cypherlabsas@gmail.com"},"directories":{},"maintainers":[{"name":"cypherlaboratory","email":"cypherlabsas@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alicesring-sag_0.1.0_1711622161153_0.6537195931187867"},"_hasShrinkwrap":false},"0.1.1":{"name":"@cypherlaboratory/alicesring-sag","version":"0.1.1","description":"A TypeScript implementation of SAG ring signatures.","main":"dist/src/index.js","module":"dist/src/index.js","types":"dist/src/index.d.ts","scripts":{"build":"npm run fmt && rm -r ./dist && tsc","test":"jest","lint":"eslint .","lint:fix":"eslint . --fix","prettier":"prettier --check .","prettier:fix":"prettier --write .","fmt:check":"npm run prettier && npm run lint","fmt":"npm run prettier:fix && npm run fmt:check"},"author":{"name":"Elli610 && LeJamon && maximedgr"},"license":"MIT","dependencies":{"@noble/hashes":"^1.3.2","ts-node":"^10.9.1"},"devDependencies":{"@types/jest":"^29.5.7","@types/node":"^20.8.7","@typescript-eslint/eslint-plugin":"^5.61.0","@typescript-eslint/parser":"^5.61.0","eslint":"^8.44.0","ts-jest":"^29.1.1","jest":"^29.7.0","prettier":"^3.0.0"},"_id":"@cypherlaboratory/alicesring-sag@0.1.1","gitHead":"85a95d58134e84094cd5d28bff5c8b3260c1eafd","_nodeVersion":"20.11.1","_npmVersion":"10.2.4","dist":{"integrity":"sha512-4EU2Ml2F3wl3+mRirzOP5N5D+/KLNMCS8HmJCgADy0w+Tl1a64OVE3sBjm7Qhi3MVNq7XEe5dnyH8cgAz46b/w==","shasum":"eadd76c403fbaee2f78019c6e00c9ae9c1670b2b","tarball":"https://registry.npmjs.org/@cypherlaboratory/alicesring-sag/-/alicesring-sag-0.1.1.tgz","fileCount":176,"unpackedSize":1782162,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIH4fGMAt/AN+e1TDdyjyrkRpPHz2d3d9zcqc6qUEXO+GAiEAx8AIdPugKy/zQfweH5RFj/t6D5keeOCEf+FyHILwYNo="}]},"_npmUser":{"name":"cypherlaboratory","email":"cypherlabsas@gmail.com"},"directories":{},"maintainers":[{"name":"cypherlaboratory","email":"cypherlabsas@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alicesring-sag_0.1.1_1711631226430_0.6502386912025526"},"_hasShrinkwrap":false},"0.1.2":{"name":"@cypherlaboratory/alicesring-sag","version":"0.1.2","description":"A TypeScript implementation of SAG ring signatures.","main":"dist/src/index.js","module":"dist/src/index.js","types":"dist/src/index.d.ts","repository":{"type":"git","url":"git+https://github.com/Cypher-Laboratory/Alice-s-Ring-SAG-TS.git"},"scripts":{"build":"npm run fmt && rm -r ./dist && tsc","test":"jest","lint":"eslint .","lint:fix":"eslint . --fix","prettier":"prettier --check .","prettier:fix":"prettier --write .","fmt:check":"npm run prettier && npm run lint","fmt":"npm run prettier:fix && npm run fmt:check"},"author":{"name":"Elli610 && LeJamon && maximedgr"},"license":"MIT","dependencies":{"@noble/hashes":"^1.3.2","crypto-browserify":"^3.12.0","ts-node":"^10.9.1"},"devDependencies":{"@types/jest":"^29.5.7","@types/node":"^20.8.7","@typescript-eslint/eslint-plugin":"^5.61.0","@typescript-eslint/parser":"^5.61.0","eslint":"^8.44.0","jest":"^29.7.0","prettier":"^3.0.0","ts-jest":"^29.1.1"},"_id":"@cypherlaboratory/alicesring-sag@0.1.2","gitHead":"57d17061b670fa95c2bc18f1309d524a6f9eec8a","bugs":{"url":"https://github.com/Cypher-Laboratory/Alice-s-Ring-SAG-TS/issues"},"homepage":"https://github.com/Cypher-Laboratory/Alice-s-Ring-SAG-TS#readme","_nodeVersion":"20.11.1","_npmVersion":"10.2.4","dist":{"integrity":"sha512-xKErHV+NqHFHBj8nPU6p3UjwtiVH6OOMLi495EG3VTyhvioKp4MJUSRkV53ZU8paGN4IBmniKo1uyX/D6PUdiw==","shasum":"cffbea4e9d6dc72bdee572631d0171425db1e6e9","tarball":"https://registry.npmjs.org/@cypherlaboratory/alicesring-sag/-/alicesring-sag-0.1.2.tgz","fileCount":179,"unpackedSize":1788887,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGajhgiU3vwOYhUYh3Lw02f0ROU4QJ5KMkbOVbNYuHyNAiAhuexUBc9pnCGWfbmwpF5ddXB9l1lK7jeVLpGFBYYG5g=="}]},"_npmUser":{"name":"cypherlaboratory","email":"cypherlabsas@gmail.com"},"directories":{},"maintainers":[{"name":"cypherlaboratory","email":"cypherlabsas@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alicesring-sag_0.1.2_1711709838708_0.7707435338899002"},"_hasShrinkwrap":false}},"time":{"created":"2024-03-28T10:36:01.031Z","0.1.0":"2024-03-28T10:36:01.459Z","modified":"2024-03-29T10:57:19.118Z","0.1.1":"2024-03-28T13:07:06.590Z","0.1.2":"2024-03-29T10:57:18.938Z"},"maintainers":[{"name":"cypherlaboratory","email":"cypherlabsas@gmail.com"}],"description":"A TypeScript implementation of SAG ring signatures.","author":{"name":"Elli610 && LeJamon && maximedgr"},"license":"MIT","readme":"# types-Ring-Signature\n\nThis repository contains a TypeScript implementation of the [Ring Signature](https://en.wikipedia.org/wiki/Ring_signature) algorithm using Spontaneous Anonymous Group (SAG).\n\n## About the implementation\n\nThe implementation is based on the [SAG algorithm](https://eprint.iacr.org/2004/027.pdf) and uses the [Elliptic Curve Cryptography](https://en.wikipedia.org/wiki/Elliptic-curve_cryptography) (ECC) to generate the keys and sign the message.\n\nWe used the implementation proposed in [Zero to Monero](https://www.getmonero.org/library/Zero-to-Monero-2-0-0.pdf) (p.36) as a reference.\n\n## Audit\n\nThe audit of this library was conducted by the company CryptoExperts [https://www.cryptoexperts.com/](https://www.cryptoexperts.com/) on March 13th, 2024. All vulnerabilities identified in the course of the audit have been fixed in agreement and under the supervision of CryptoExperts.  \n\n## Usage\n\n```typescript\nimport { RingSignature , Curve , CurveName , Point } from '@cypherlab/types-ring-signature';\n\nconst curve: Curve = new Curve(CurveName.SECP256K1);\nconst ring: Point[] = []; // your ring of public keys\nconst message = 'Hello World!';\n\nconst signerPrivateKey = BigInt('your private key');\n\n// Sign\nconst signature: RingSignature = RingSignature.sign(\n  ring,\n  signerPrivateKey,\n  message,\n  curve,\n);\n\n// Verify\nconsole.log(\n  \"Is signature verified? \", signature.verify()\n);\n\n// Export to jsonString\nconst jsonString = signature.toJsonString();\n\n// Import from jsonString\nconst retrievedFromJson = RingSignature.fromJsonString(jsonString);\n```\n\n## Dependencies\n\n| Dependency        | Version | repo                                    |audit report                                     |dependencies|\n|-------------------|---------|-----------------------------------------|-------------------------------------------------|------------|\n| @noble/hashes     | ^1.3.2  |[GitHub](https://github.com/paulmillr/noble-hashes)|[Report](https://cure53.de/pentest-report_hashing-libs.pdf)|[NPM](https://www.npmjs.com/package/@noble/hashes?activeTab=dependencies)|\n\n## Dev Dependencies\n\n| Dev Dependency                      | Version  | Repository                                                                          |\n|-------------------------------------|----------|-------------------------------------------------------------------------------------|\n| @types/jest                         | ^29.5.7  | [GitHub](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/jest) |\n| @types/node                         | ^20.8.7  | [GitHub](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node) |\n| @typescript-eslint/eslint-plugin    | ^5.61.0  | [GitHub](https://github.com/typescript-eslint/typescript-eslint)                    |\n| @typescript-eslint/parser           | ^5.61.0  | [GitHub](https://github.com/typescript-eslint/typescript-eslint)                    |\n| eslint                              | ^8.44.0  | [GitHub](https://github.com/eslint/eslint)                                          |\n| jest                                | ^29.7.0  | [GitHub](https://github.com/facebook/jest)                                          |\n| prettier                            | ^3.0.0   | [GitHub](https://github.com/prettier/prettier)                                      |\n| ts-jest                             | ^29.1.1  | [GitHub](https://github.com/kulshekhar/ts-jest)                                     |\n| ts-node                             | ^10.9.1  | [GitHub](https://github.com/TypeStrong/ts-node)                                     |\n\n## Spontaneous Anonymous Group (SAG) Signatures\n### Group Setup\nWhen setting up a group for cryptographic purposes, such as for a Spontaneous Anonymous Group (SAG) signature scheme, there are two primary methods to establish the group members' public keys: \n\n- **using existing public keys** of the members from publicly available data such as blockchains. This method is suitable for scenarios where the group members have a common caracteristics, such as being part of the same organization or having a specific role. For example, a group of members of a company's board of directors can be identified by their public keys, which are publicly available on the company's website.\n- **using a group key generation algorithm** to generate the public keys of the members. This method is suitable for scenarios where the group members are not known in advance, such as in a voting system. For example, a group of voters can be identified by their public keys, which are generated by the voting system's key generation algorithm.\n\n### Signature Generation\nLet $l$ be the number of members in the group.  \nLet $R$ be a set of public keys of the group members such as $R$ = { $K_{0}$ , $K_{1}$ , ..., $K_{n}$ } where n be the number of members in the group minus 1 ($l = n + 1$).   \nLet $m$ be the digest of the message to be signed.   \nLet $H$ be a hash function.   \nLet $k$ be a random integer in the range $[1, N-1]$. This is the private key of the signer.  \nLet $\\pi$ be the signer position in the group. This is a random integer in the range $[0, n]$.  \n\nThe signer computes the following:\n- Generates a random integer $\\alpha$ in the range [1, N-1]\n- Generates random responses *r* = { $r_{0}$ , $r_{1}$ , ... , $r_{\\pi-1}$, $r_{\\pi+1}$, ... , $r_{n}$ } where $r_{i}$ ($0 <= i <= n$ excluding $\\pi$) is a random integer in the range $[1, N-1]$\n- Computes $c_{\\pi+1} = H(R, m, [\\alpha G])$\n- For $j$ in $[\\pi + 1, l + \\pi]$ computes the following:\n    - $i = mod(j, l)$ -> allows to loop over the group members\n    - $s = i - 1$ if $i > 0$ else $l - 1$ -> $s = i - 1$ except when $i = 0$. In this case, $s = l - 1$\n    - $c_{i+1} = H(R, m, [r_{s}G + c_{s}K_{s}])$\n- Define the signer's response to verify $\\alpha = r_{\\pi} + c_{\\pi}k$ ($mod$ $N$)\n\nThe signature contains the following:\n- the ring of public keys $R$\n- the challenge $c_{1}$\n- the responses $r$ = { $r_{0}$ , $r_{1}$ , ... , $r_{n}$ }\n  \n\n### Signature Verification\nKnown data:\n- the ring of public keys $R$\n- the seed $c_{0}$\n- the responses $r$ = { $r_{0}$ , $r_{1}$ , ... , $r_{n}$ }\n- the message $m$\n\nThe signature is valid if and only if the signature has been generated using one of the group member's private keys.\n\nThe verifier computes the following:\n- For $i = 2$ to $n$, with $i$ wrapping around to 1 after $n$:\n    - $c_{i}$' = $H( R, m, [ r_{i-1} G$  + $c_{i-1}$' $K_{i-1}$]) if $i ≠ 1$ else $c_{i}$' = $H(R, m, [r_{1}G + c_{1}K_{1}])$\n- If $c_{1}$' = $c_{1}$ then the signature is valid, else it is invalid.\n\n\n## Detailed implementation \n\n### RingSignature.sign\n\nThis method is designed to compute a ring signature by directly utilizing a private key as input. It's tailored for scenarios where you do not use a wallet for key management. The RingSignature.sign function needs the private key to generate the ring signature.\n\n#### 1. Sort the ring by x ascending (and y ascending if x is equal)\nLet $\\pi$ be the signer position in the group. This is an integer in the range $[0, n]$.\n\n#### 2. Generate Random Number $\\alpha$\nIt will be use as the nonce.\n- **Function:** `randomBigint`\n- **Location:** `src/utils/randomNumber.ts`\n- **Description:** Generates a random bigint in the range [1, max[.\n\n```typescript\nexport function randomBigint(max: bigint): bigint\n```\n\n#### 3. Compute $c_{\\pi+1}$\n $c_{\\pi+1} = H(R, m, [\\alpha G])$\n- **Function:** `computeC`\n- **Location:** `src/ringSignatures.ts`\n- **Description:** Compute a c value.\n- **Remarks:**\n   * This function is used to compute the c value of a ring-signature.\n   * Either 'alpha' or all the other keys of 'params' must be set..\n\n```typescript\n  private static computeC(\n    ring: Point[],\n    messageDigest: bigint,\n    params: {\n      previousR?: bigint;\n      previousC?: bigint;\n      previousPubKey?: Point;\n      alpha?: bigint;\n    },\n    curve: Curve,\n    config?: SignatureConfig,\n  ): bigint \n```\n#### 4. Compute the challenges.\nGenerates random responses *r* = {$r_{1}$, ... , $r_{\\pi-1}$, $r_{\\pi+1}$, ... , $r_{n}$ } where $r_{i}$ ($0 <= i <= n$ excluding $\\pi$) is a random integer in the range $[1, N-1]$  \nFor i = ${\\pi+1}$, ${\\pi+2}$ , ..., n, 1, 2, ..., ${\\pi-1}$ calculate, replacing n + 1 → 1,\n\n$c_{i+1} = H(R, m, [r_{s}G - c_{s}K_{s}])$\n\n- **Function:** `RingSignature.signature`\n- **Location:** `src/ringSignature.ts`\n- **Description:** Generate an incomplete ring signature.\n\n```typescript\n  private static signature(\n    curve: Curve,\n    ring: Point[],\n    ceePiPlusOne: bigint,\n    signerIndex: number,\n    messageDigest: bigint,\n    config?: SignatureConfig,\n  ): {\n    ring: Point[];\n    cees: bigint[];\n    signerIndex: number;\n    responses: bigint[];\n  }\n```\n\n#### 5. Compute the signer response $r_{\\pi}$\n$r_{\\pi}$ such that $\\alpha = r_{\\pi} - c_{\\pi}k$ ($mod$ $N$).\n- **Function:** `piSignature`\n- **Location:** `src/signature/piSignature.ts`\n- **Description:** Compute the signature from the actual signer.\n\n```typescript\nexport function piSignature(\n  alpha: bigint,\n  c: bigint,\n  signerPrivKey: bigint,\n  curve: Curve,\n): bigint \n```\n\n#### 6. Return the ring signature\nReturn the ring-signature.\n- **Function:** `constructor`\n- **Location:** `src/ringSignature.ts`\n- **Description:** Ring signature class constructor.\n\n```typescript\n  constructor(\n    message: string,\n    ring: Point[],\n    c: bigint,\n    responses: bigint[],\n    curve: Curve,\n    config?: SignatureConfig,\n  ) \n```\n\n### RingSignature.verify\nThis method verifies if a ring signature is valid.\n\n#### 1. Verify the ring signature\n- **Function:** `RingSignature.verify.ts`\n- **Location:** `src/ringSignature.ts`\n- **Description:** Verify a RingSignature.\n\n```typescript\n  verify(): boolean\n```\n\n## Sponsors\n\nWe would like to thank the XRPL Foundation [https://xrpl.org/](https://xrpl.org/) for their support and funding, which have allowed this audited library to be developed for the benefit of many.  ","readmeFilename":"README.md","homepage":"https://github.com/Cypher-Laboratory/Alice-s-Ring-SAG-TS#readme","repository":{"type":"git","url":"git+https://github.com/Cypher-Laboratory/Alice-s-Ring-SAG-TS.git"},"bugs":{"url":"https://github.com/Cypher-Laboratory/Alice-s-Ring-SAG-TS/issues"}}