{"_id":"@cypher-laboratory/alicesring-sag","_rev":"5-3b71f2c4e099dd712c95bcb7dc1b9002","name":"@cypher-laboratory/alicesring-sag","description":"A TypeScript implementation of SAG ring signatures.","dist-tags":{"latest":"0.2.1","snap":"0.2.4"},"versions":{"0.1.2":{"name":"@cypher-laboratory/alicesring-sag","version":"0.1.2","author":{"name":"Elli610 && LeJamon && maximedgr"},"license":"MIT","_id":"@cypher-laboratory/alicesring-sag@0.1.2","maintainers":[{"name":"lejamon","email":"lejamon.c@protonmail.com"},{"name":"elli610","email":"niktoua256@gmail.com"},{"name":"cypherlaboratory","email":"cypherlabsas@gmail.com"}],"homepage":"https://github.com/Cypher-Laboratory/Alice-s-Ring-SAG-TS#readme","bugs":{"url":"https://github.com/Cypher-Laboratory/Alice-s-Ring-SAG-TS/issues"},"dist":{"shasum":"453d7d7a0e1dc0b94599209863ba518081ec042e","tarball":"https://registry.npmjs.org/@cypher-laboratory/alicesring-sag/-/alicesring-sag-0.1.2.tgz","fileCount":179,"integrity":"sha512-G1QBHCTMNj25IYYzXnw7RJWzji0xfAwcBjmVt/n95buhRULbgC75iqzbeS3NzM50m83w1JNFdLQW+1DR8eS7JA==","signatures":[{"sig":"MEQCIA6MwGUfki/C/6lPzs+ojht36UlZQa8UE/ob6UIznu81AiBRb0TMaEr8YmpNe8lMA8zU0XemAsmzgd7EfGwKP/n02g==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1788756},"main":"dist/src/index.js","types":"dist/src/index.d.ts","module":"dist/src/index.js","gitHead":"57d17061b670fa95c2bc18f1309d524a6f9eec8a","scripts":{"fmt":"npm run prettier:fix && npm run fmt:check","lint":"eslint .","test":"jest","build":"npm run fmt && rm -r ./dist && tsc","lint:fix":"eslint . --fix","prettier":"prettier --check .","fmt:check":"npm run prettier && npm run lint","prettier:fix":"prettier --write ."},"_npmUser":{"name":"elli610","email":"niktoua256@gmail.com"},"repository":{"url":"git+https://github.com/Cypher-Laboratory/Alice-s-Ring-SAG-TS.git","type":"git"},"_npmVersion":"10.5.0","description":"A TypeScript implementation of SAG ring signatures.","directories":{},"_nodeVersion":"21.7.3","dependencies":{"ts-node":"^10.9.1","@noble/hashes":"^1.3.2","crypto-browserify":"^3.12.0"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^8.44.0","ts-jest":"^29.1.1","prettier":"^3.0.0","@types/jest":"^29.5.7","@types/node":"^20.8.7","@typescript-eslint/parser":"^5.61.0","@typescript-eslint/eslint-plugin":"^5.61.0"},"_npmOperationalInternal":{"tmp":"tmp/alicesring-sag_0.1.2_1713948439085_0.4807433190965613","host":"s3://npm-registry-packages"}},"0.2.0":{"name":"@cypher-laboratory/alicesring-sag","version":"0.2.0","author":{"name":"Elli610 && LeJamon && maximedgr"},"license":"MIT","_id":"@cypher-laboratory/alicesring-sag@0.2.0","maintainers":[{"name":"lejamon","email":"lejamon.c@protonmail.com"},{"name":"elli610","email":"niktoua256@gmail.com"},{"name":"cypherlaboratory","email":"cypherlabsas@gmail.com"}],"homepage":"https://github.com/Cypher-Laboratory/Alice-s-Ring-SAG-TS#readme","bugs":{"url":"https://github.com/Cypher-Laboratory/Alice-s-Ring-SAG-TS/issues"},"dist":{"shasum":"ff6c42318e7346c1f29931e2be86c3a9db32e0e1","tarball":"https://registry.npmjs.org/@cypher-laboratory/alicesring-sag/-/alicesring-sag-0.2.0.tgz","fileCount":182,"integrity":"sha512-UQzrdBGF0GmLamXOBxl75N33c3fhYIZpUFtSkuFZw3BIH+t9EABBsOVquEGV4QM6M2+xowm9g57LgB+BTR3Xyg==","signatures":[{"sig":"MEYCIQCxCXQQditGQSxj9hMYh7sBi7AYycZQe+6J0WbMwN8atAIhAKjdYjKDwqHPFuvk6B9ps4VYEs0krtZMgnk88DJwyyg/","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1788895},"main":"dist/src/index.js","types":"dist/src/index.d.ts","module":"dist/src/index.js","gitHead":"f53914db3592cc56e02972f0f08031948da3a983","scripts":{"fmt":"npm run prettier:fix && npm run fmt:check","lint":"eslint .","test":"jest","build":"npm run fmt && rm -r ./dist && tsc","lint:fix":"eslint . --fix","prettier":"prettier --check .","fmt:check":"npm run prettier && npm run lint","prettier:fix":"prettier --write ."},"_npmUser":{"name":"elli610","email":"niktoua256@gmail.com"},"repository":{"url":"git+https://github.com/Cypher-Laboratory/Alice-s-Ring-SAG-TS.git","type":"git"},"_npmVersion":"10.5.0","description":"A TypeScript implementation of SAG ring signatures.","directories":{},"_nodeVersion":"21.7.3","dependencies":{"ts-node":"^10.9.1","@noble/hashes":"^1.3.2","crypto-browserify":"^3.12.0"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^8.44.0","ts-jest":"^29.1.1","prettier":"^3.0.0","@types/jest":"^29.5.7","@types/node":"^20.8.7","@typescript-eslint/parser":"^5.61.0","@typescript-eslint/eslint-plugin":"^5.61.0"},"_npmOperationalInternal":{"tmp":"tmp/alicesring-sag_0.2.0_1714987726822_0.22026391918548405","host":"s3://npm-registry-packages"}},"0.2.1":{"name":"@cypher-laboratory/alicesring-sag","version":"0.2.1","author":{"name":"Elli610 && LeJamon && maximedgr"},"license":"MIT","_id":"@cypher-laboratory/alicesring-sag@0.2.1","maintainers":[{"name":"lejamon","email":"lejamon.c@protonmail.com"},{"name":"elli610","email":"niktoua256@gmail.com"},{"name":"cypherlaboratory","email":"cypherlabsas@gmail.com"}],"homepage":"https://github.com/Cypher-Laboratory/Alice-s-Ring-SAG-TS#readme","bugs":{"url":"https://github.com/Cypher-Laboratory/Alice-s-Ring-SAG-TS/issues"},"dist":{"shasum":"8c10e86afc22938949dcc80fa6abbfd3f0211cdf","tarball":"https://registry.npmjs.org/@cypher-laboratory/alicesring-sag/-/alicesring-sag-0.2.1.tgz","fileCount":71,"integrity":"sha512-oE1wylXH65TLoxYj2HSRa/jEFmyXV60+Ryuegdm9aaq2P6GC15ysAe2a78QAUCg3ABorULeoEdFAzt6gmWjoSA==","signatures":[{"sig":"MEQCIHNgL5AplKHas/G3CNX+PNlgdNhXpJqiS+Ju5dgK2QipAiBOl0FQ27lokyOm52B/IR/SU5rxw1/gB8PnFQeymSEsew==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1568838},"main":"dist/src/index.js","types":"dist/src/index.d.ts","module":"dist/src/index.js","gitHead":"5600ae70449ca1ec6d81699a59ba8e126b57b931","scripts":{"fmt":"npm run prettier:fix && npm run fmt:check","lint":"eslint .","test":"jest","build":"npm run fmt && rm -r ./dist && tsc","lint:fix":"eslint . --fix","prettier":"prettier --check .","fmt:check":"npm run prettier && npm run lint","prettier:fix":"prettier --write ."},"_npmUser":{"name":"elli610","email":"niktoua256@gmail.com"},"repository":{"url":"git+https://github.com/Cypher-Laboratory/Alice-s-Ring-SAG-TS.git","type":"git"},"_npmVersion":"10.5.0","description":"A TypeScript implementation of SAG ring signatures.","directories":{},"_nodeVersion":"21.7.3","dependencies":{"ts-node":"^10.9.1","@noble/hashes":"^1.3.2","crypto-browserify":"^3.12.0"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^8.44.0","ts-jest":"^29.1.1","prettier":"^3.0.0","@types/jest":"^29.5.7","@types/node":"^20.8.7","@typescript-eslint/parser":"^5.61.0","@typescript-eslint/eslint-plugin":"^5.61.0"},"_npmOperationalInternal":{"tmp":"tmp/alicesring-sag_0.2.1_1716889620732_0.7975314912390385","host":"s3://npm-registry-packages"}},"0.2.2":{"name":"@cypher-laboratory/alicesring-sag","version":"0.2.2","author":{"name":"Elli610 && LeJamon && maximedgr"},"license":"MIT","_id":"@cypher-laboratory/alicesring-sag@0.2.2","homepage":"https://github.com/Cypher-Laboratory/Alice-s-Ring-SAG-TS#readme","bugs":{"url":"https://github.com/Cypher-Laboratory/Alice-s-Ring-SAG-TS/issues"},"dist":{"shasum":"d8cae34c00ee3edcf0baebdb2f6e09566c5101a7","tarball":"https://registry.npmjs.org/@cypher-laboratory/alicesring-sag/-/alicesring-sag-0.2.2.tgz","fileCount":68,"integrity":"sha512-I7AtGX4VfZM5JQX9mM71vGgxvUmnghCM4XFxk3EJbRpQrsm8Yd+wRm2MrMDRiNIM/r/GNuBT9TRVYamrwlsbZQ==","signatures":[{"sig":"MEMCIA1VIfBApWHY0bKQVCY736XAcBDVTDkO6trdadLsIoaPAh8pMqMM3ltCAslilu5NdaZMyEt34JA+x8J0Y/T2BT5n","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1483225},"main":"dist/src/index.js","types":"dist/src/index.d.ts","module":"dist/src/index.js","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 '@cypher-laboratory/alicesring-sag';\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.  \n","gitHead":"35d84caa22a8d756a1f6374ba9c6e241881a86d7","scripts":{"fmt":"npm run prettier:fix && npm run fmt:check","lint":"eslint .","test":"jest","build":"npm run fmt && rm -r ./dist && tsc","lint:fix":"eslint . --fix","prettier":"prettier --check .","fmt:check":"npm run prettier && npm run lint","prettier:fix":"prettier --write ."},"_npmUser":{"name":"elli610","email":"niktoua256@gmail.com"},"repository":{"url":"git+https://github.com/Cypher-Laboratory/Alice-s-Ring-SAG-TS.git","type":"git"},"_npmVersion":"10.5.0","description":"A TypeScript implementation of SAG ring signatures.","directories":{},"_nodeVersion":"21.7.3","dependencies":{"ts-node":"^10.9.1","@noble/hashes":"^1.3.2","crypto-browserify":"^3.12.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"jest":"^29.7.0","eslint":"^8.44.0","ts-jest":"^29.1.1","prettier":"^3.0.0","@types/jest":"^29.5.7","@types/node":"^20.8.7","@typescript-eslint/parser":"^5.61.0","@typescript-eslint/eslint-plugin":"^5.61.0"},"_npmOperationalInternal":{"tmp":"tmp/alicesring-sag_0.2.2_1719825699951_0.13868891703379105","host":"s3://npm-registry-packages"}},"0.2.3":{"name":"@cypher-laboratory/alicesring-sag","version":"0.2.3","author":{"name":"Elli610 && LeJamon && maximedgr"},"license":"MIT","_id":"@cypher-laboratory/alicesring-sag@0.2.3","homepage":"https://github.com/Cypher-Laboratory/Alice-s-Ring-SAG-TS#readme","bugs":{"url":"https://github.com/Cypher-Laboratory/Alice-s-Ring-SAG-TS/issues"},"dist":{"shasum":"df32bc228a4723787d99ce2ab02ed25189827135","tarball":"https://registry.npmjs.org/@cypher-laboratory/alicesring-sag/-/alicesring-sag-0.2.3.tgz","fileCount":60,"integrity":"sha512-kSU5jEjeIC4xE+QCk4blH5wek9LTd/0CQxlwZn22zVIaq2C7gDtpQBv/7Je2psMHWzkFYZ9HsFwnYRMbHqSQTA==","signatures":[{"sig":"MEYCIQDAhgPaShRehOTiCeMaN809FpzX9mXUN2QnMUfozjUpTgIhAKh/UOld2q+SFOxwmnkjCgdo12REfqCiACGH984laGOZ","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1473744},"main":"dist/src/index.js","types":"dist/src/index.d.ts","module":"dist/src/index.js","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 '@cypher-laboratory/alicesring-sag';\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.  \n","gitHead":"017e2e43bbc0b05766c8237a8b7400d20f5a9a9e","scripts":{"fmt":"npm run prettier:fix && npm run fmt:check","lint":"eslint .","test":"jest","build":"npm run fmt && rm -r ./dist && tsc","lint:fix":"eslint . --fix","prettier":"prettier --check .","fmt:check":"npm run prettier && npm run lint","prettier:fix":"prettier --write ."},"_npmUser":{"name":"elli610","email":"niktoua256@gmail.com"},"repository":{"url":"git+https://github.com/Cypher-Laboratory/Alice-s-Ring-SAG-TS.git","type":"git"},"_npmVersion":"10.5.0","description":"A TypeScript implementation of SAG ring signatures.","directories":{},"_nodeVersion":"21.7.3","dependencies":{"ts-node":"^10.9.1","@noble/hashes":"^1.3.2","crypto-browserify":"^3.12.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"jest":"^29.7.0","eslint":"^8.44.0","ts-jest":"^29.1.1","prettier":"^3.0.0","@types/jest":"^29.5.7","@types/node":"^20.8.7","@typescript-eslint/parser":"^5.61.0","@typescript-eslint/eslint-plugin":"^5.61.0"},"_npmOperationalInternal":{"tmp":"tmp/alicesring-sag_0.2.3_1719829197946_0.18867856962051","host":"s3://npm-registry-packages"}},"0.2.4":{"name":"@cypher-laboratory/alicesring-sag","version":"0.2.4","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":"@cypher-laboratory/alicesring-sag@0.2.4","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 '@cypher-laboratory/alicesring-sag';\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.  \n","readmeFilename":"README.md","gitHead":"017e2e43bbc0b05766c8237a8b7400d20f5a9a9e","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":"21.7.3","_npmVersion":"10.5.0","dist":{"integrity":"sha512-zyNSQBGmI+G6msWYyZlfZvm2vZiX0U4qr2Dp6ekHoXrLlKUslX6b8AKIMBD4wGA/OtFm7+nSfTaJWt4OHJTI+Q==","shasum":"7b211146010f218e07d33902701cbce374410b70","tarball":"https://registry.npmjs.org/@cypher-laboratory/alicesring-sag/-/alicesring-sag-0.2.4.tgz","fileCount":60,"unpackedSize":1473138,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCxaOLJTXUQAV1cWN6Rv3q96OuwyF+zXjy5Lun7ChcvswIgUVVGdQtEQ3ACpHLA3uGSqGQUrMo+kMYsEZunb2t54VA="}]},"_npmUser":{"name":"elli610","email":"niktoua256@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/alicesring-sag_0.2.4_1719832401305_0.15077444769812853"},"_hasShrinkwrap":false}},"time":{"created":"2024-04-24T08:47:18.972Z","modified":"2024-07-01T11:13:21.735Z","0.1.2":"2024-04-24T08:47:19.339Z","0.2.0":"2024-05-06T09:28:47.060Z","0.2.1":"2024-05-28T09:47:00.940Z","0.2.2":"2024-07-01T09:21:40.132Z","0.2.3":"2024-07-01T10:19:58.158Z","0.2.4":"2024-07-01T11:13:21.549Z"},"maintainers":[{"name":"lejamon","email":"lejamon.c@protonmail.com"},{"name":"elli610","email":"niktoua256@gmail.com"},{"name":"cypherlaboratory","email":"cypherlabsas@gmail.com"}],"author":{"name":"Elli610 && LeJamon && maximedgr"},"repository":{"url":"git+https://github.com/Cypher-Laboratory/Alice-s-Ring-SAG-TS.git","type":"git"},"license":"MIT","homepage":"https://github.com/Cypher-Laboratory/Alice-s-Ring-SAG-TS#readme","bugs":{"url":"https://github.com/Cypher-Laboratory/Alice-s-Ring-SAG-TS/issues"},"readme":"","readmeFilename":""}