paragonie / ristretto
为Ristretto255群提供类型安全的API
v0.1.0
2022-06-10 05:51 UTC
Requires
- php: ^8.1
- paragonie/constant_time_encoding: ^2
- paragonie/hidden-string: ^2
- paragonie/sodium_compat: ^1
Requires (Dev)
- phpunit/phpunit: ^9
- vimeo/psalm: ^4
Suggests
- ext-sodium: Better performance.
This package is auto-updated.
Last update: 2024-09-10 11:04:10 UTC
README
实现一个类型安全的API,用于在PHP项目中处理Ristretto群。
要求
- PHP 8.1或更高版本
安装
composer require paragonie/ristretto
文档
有两种基本类型:ScalarValue
和GroupElement
。
ScalarValue
对象封装一个介于0和Ristretto群阶L
之间的大整数。
GroupElement
对象封装Ristretto群的群元素。
如果类比有帮助,在Ed25519和X25519的世界中,ScalarValue
是你的密钥,而GroupElement
是你的公钥。
因此,还有一个SecretKey
和PublicKey
类,它包含一些基本的辅助方法,以方便使用。
用法
您可以使用multBase()
将标量转换为群元素,然后使用scalarPointMultiply()
执行交换群操作(例如Diffie-Hellman)。
<?php use ParagonIE\Ristretto\{GroupElement, ScalarValue}; $aliceSecret = ScalarValue::random(); $alicePublic = $aliceSecret->multBase(); $bobSecret = ScalarValue::random(); $bobPublic = $bobSecret->multBase(); // You can perform a similar commutative group action $aliceToBob = $aliceSecret->scalarPointMultiply($bobPublic); $bobToAlice = $bobSecret->scalarPointMultiply($alicePublic); var_dump($aliceToBob->equals($bobToAlice)); // bool(true)
否则,大多数操作都在给定类型内进行(GroupElement到GroupElement,ScalarValue到ScalarValue)。
GroupElement
<?php use ParagonIE\Ristretto\{GroupElement}; $x = GroupElement::random(); $y = GroupElement::random(); $z = $x->add($y); $w = $z->sub($y); var_dump($w->equals($x)); // bool(true)
ScalarValue
示例
这是一个libsodium示例协议的PHP实现。
执行一个安全的两方计算
f(x) = p(x)^k
。由第一方在将随机可逆标量r
用于遮蔽后,发送给第二方的输入为x
,而k
是第二方唯一知道的秘密密钥。p(x)
是一个哈希到群函数。
<?php use ParagonIE\Ristretto\{GroupElement}; // -------- First party -------- Send blinded p(x) $x = random_bytes(64); // Compute px = p(x), a group element derived from x $px = GroupElement::fromHash($x); // Compute a = p(x) * g^r $r = ScalarValue::random(); $gr = $r->multBase(); $a = $px->add($gr); // -------- Second party -------- Send g^k and a^k $k = ScalarValue::random(); // Compute v = g^k $v = $k->multBase(); // Compute b = a^k $b = $k->scalarPointMultiply($a); // -------- First party -------- Unblind f(x) // Compute vir = v^(-r) $ir = $r->negate(); $vir = $v->scalarPointMultiply($ir); // Compute f(x) = b * v^(-r) = (p(x) * g^r)^k * (g^k)^(-r) // = (p(x) * g)^k * g^(-k) = p(x)^k $fx = $b->add($vir); // --------- Correctness testing ----------- // If you knew both p(x) and k, you could calculate it directly. // Directly calculate p(x)^k with both parties' secrets $pxk = $px->scalarPointMultiply($k); var_dump($fx->equals($pxk)); // bool(true)