{"id":20790372,"url":"https://github.com/paragonie/ristretto-php","last_synced_at":"2025-07-14T08:32:40.186Z","repository":{"id":57703178,"uuid":"501915965","full_name":"paragonie/ristretto-php","owner":"paragonie","description":"Implements a type-safe API for working with the Ristretto Group in PHP projects.","archived":false,"fork":false,"pushed_at":"2022-06-10T05:53:50.000Z","size":7,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-06-20T22:16:07.231Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/paragonie.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-06-10T05:48:40.000Z","updated_at":"2024-05-30T05:47:16.000Z","dependencies_parsed_at":"2022-08-29T05:31:10.896Z","dependency_job_id":null,"html_url":"https://github.com/paragonie/ristretto-php","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/paragonie/ristretto-php","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paragonie%2Fristretto-php","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paragonie%2Fristretto-php/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paragonie%2Fristretto-php/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paragonie%2Fristretto-php/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/paragonie","download_url":"https://codeload.github.com/paragonie/ristretto-php/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paragonie%2Fristretto-php/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265262625,"owners_count":23736433,"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":[],"created_at":"2024-11-17T15:34:24.263Z","updated_at":"2025-07-14T08:32:40.150Z","avatar_url":"https://github.com/paragonie.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Ristretto (PHP)\n\n[![Build Status](https://github.com/paragonie/ristretto-php/actions/workflows/ci.yml/badge.svg)](https://github.com/paragonie/ristretto-php/actions)\n[![Latest Stable Version](https://poser.pugx.org/paragonie/ristretto/v/stable)](https://packagist.org/packages/paragonie/ristretto)\n[![Latest Unstable Version](https://poser.pugx.org/paragonie/ristretto/v/unstable)](https://packagist.org/packages/paragonie/ristretto)\n[![License](https://poser.pugx.org/paragonie/ristretto/license)](https://packagist.org/packages/paragonie/ristretto)\n[![Downloads](https://img.shields.io/packagist/dt/paragonie/ristretto.svg)](https://packagist.org/packages/paragonie/ristretto)\n\nImplements a type-safe API for working with [the Ristretto Group](https://ristretto.group)\nin PHP projects.\n\n## Requirements\n\n* **PHP 8.1 or newer**\n\n## Installing\n\n```terminal\ncomposer require paragonie/ristretto\n```\n\n## Documentation\n\nThere are two basic types: `ScalarValue` and `GroupElement`.\n\nThe `ScalarValue` object wraps a big integer between 0 and the order of the Ristretto Group, `L`.\n\nThe `GroupElement` object wraps a group element of the Ristretto Group.\n\nIf an analogy helps, in the world of Ed25519 and X25519, the `ScalarValue` is your secret key, \nand `GroupElement` is your public key.\n\nFor that reason, there are also a `SecretKey` and `PublicKey` class, which contains some\nbasic helper methods for ease-of-use.\n\n## Usage\n\nYou can convert from scalars to group elements with `multBase()`, and then use\n`scalarPointMultiply()` to perform a commutative group action (e.g. Diffie-Hellman).\n\n```php\n\u003c?php\nuse ParagonIE\\Ristretto\\{GroupElement, ScalarValue};\n\n$aliceSecret = ScalarValue::random();\n$alicePublic = $aliceSecret-\u003emultBase();\n$bobSecret = ScalarValue::random();\n$bobPublic = $bobSecret-\u003emultBase();\n\n// You can perform a similar commutative group action\n$aliceToBob = $aliceSecret-\u003escalarPointMultiply($bobPublic);\n$bobToAlice = $bobSecret-\u003escalarPointMultiply($alicePublic);\nvar_dump($aliceToBob-\u003eequals($bobToAlice)); // bool(true)\n```\n\nOtherwise, most operations are within a given type (GroupElement to GroupElement,\nScalarValue to ScalarValue).\n\n### GroupElement\n\n```php\n\u003c?php\nuse ParagonIE\\Ristretto\\{GroupElement};\n\n$x = GroupElement::random();\n$y = GroupElement::random();\n\n$z = $x-\u003eadd($y);\n$w = $z-\u003esub($y);\nvar_dump($w-\u003eequals($x)); // bool(true)\n```\n\n### ScalarValue\n\n## Example\n\nThis is a PHP implementation of the [libsodium example protocol](https://libsodium.gitbook.io/doc/advanced/point-arithmetic/ristretto#example).\n\n\u003e Perform a secure two-party computation of `f(x) = p(x)^k`. `x` is the input sent to the second party \n\u003e by the first party after blinding it using a random invertible scalar `r`, and `k` is a secret key\n\u003e only known by the second party. `p(x)` is a hash-to-group function.\n\n```php\n\u003c?php\nuse ParagonIE\\Ristretto\\{GroupElement};\n\n// -------- First party -------- Send blinded p(x)\n$x = random_bytes(64);\n\n// Compute px = p(x), a group element derived from x\n$px = GroupElement::fromHash($x);\n\n// Compute a = p(x) * g^r\n$r = ScalarValue::random();\n$gr = $r-\u003emultBase();\n$a = $px-\u003eadd($gr);\n\n// -------- Second party -------- Send g^k and a^k\n$k = ScalarValue::random();\n\n// Compute v = g^k\n$v = $k-\u003emultBase();\n\n// Compute b = a^k\n$b = $k-\u003escalarPointMultiply($a);\n\n// -------- First party -------- Unblind f(x)\n// Compute vir = v^(-r)\n$ir = $r-\u003enegate();\n$vir = $v-\u003escalarPointMultiply($ir);\n\n// Compute f(x) = b * v^(-r) = (p(x) * g^r)^k * (g^k)^(-r)\n//              = (p(x) * g)^k * g^(-k) = p(x)^k\n$fx = $b-\u003eadd($vir);\n\n// --------- Correctness testing -----------\n// If you knew both p(x) and k, you could calculate it directly.\n\n// Directly calculate p(x)^k with both parties' secrets\n$pxk = $px-\u003escalarPointMultiply($k);\nvar_dump($fx-\u003eequals($pxk)); // bool(true)\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fparagonie%2Fristretto-php","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fparagonie%2Fristretto-php","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fparagonie%2Fristretto-php/lists"}