PHP Classes

File: tests/RistrettoTest.php

Recommend this page to a friend!
  Classes of Scott Arciszewski   Ristretto PHP   tests/RistrettoTest.php   Download  
File: tests/RistrettoTest.php
Role: Class source
Content type: text/plain
Description: Class source
Class: Ristretto PHP
Manipulate values in type safe way using classes
Author: By
Last change:
Date: 1 year ago
Size: 6,076 bytes
 

Contents

Class file image Download
<?php
declare(strict_types=1);
namespace
ParagonIE\Ristretto\Tests;

use
Exception;
use
ParagonIE\Ristretto\{
   
Ristretto,
   
GroupElement,
   
PublicKey,
   
ScalarValue,
   
SecretKey
};
use
ParagonIE\HiddenString\HiddenString;
use
PHPUnit\Framework\TestCase;
use
SodiumException;

/**
 * @covers Ristretto, PublicKey, SecretKey, ScalarValue, GroupElement
 */
class KeyTest extends TestCase
{
   
/**
     * @throws SodiumException
     */
   
public function testPointArithmetic(): void
   
{
       
$sk = SecretKey::generate();
       
$pk = $sk->getPublicKey();

       
$random = ScalarValue::random();
       
$r = $random->multBase();

       
$added = $pk->add($r);
       
$this->assertFalse($added->equals($pk));
       
$subbed = $added->sub($r);
       
$this->assertTrue($pk->equals($subbed));
    }

   
/**
     * @throws Exception
     */
   
public function testScalarArithmetic(): void
   
{
       
// random scalars
       
$zero = $this->zero();
       
$a = ScalarValue::random();
       
$b = ScalarValue::random();
       
$r = ScalarValue::random();
       
$this->assertNotSame($a->hex(), $zero->hex(), 'RNG failure: a == 0');
       
$this->assertNotSame($b->hex(), $zero->hex(), 'RNG failure: b == 0');
       
$this->assertNotSame($r->hex(), $zero->hex(), 'RNG failure: r == 0');
       
$this->assertNotSame($a->hex(), $b->hex(), 'RNG failure: a == b');
       
$this->assertNotSame($a->hex(), $r->hex(), 'RNG failure: a == r');
       
$this->assertNotSame($b->hex(), $r->hex(), 'RNG failure: b == r');

       
// addition
       
$c = $a->add($b);
       
$this->assertNotSame($a->hex(), $c->hex(), 'a + b != a');
       
// subtraction
       
$d = $c->sub($b);
       
$this->assertSame($a->hex(), $d->hex(), 'a + b - b == a');
       
// negation
       
$e = $c->add($b->negate());
       
$this->assertSame($a->hex(), $e->hex(), 'a + b + (-b) == a');
       
// multiplication
       
$ar = $a->mul($r);
       
$br = $b->mul($r);
       
$this->assertNotSame($ar->hex(), $br->hex(), 'given (a != b): a * r != b * r');
       
// multiplicative inverse
       
$ir = $r->invert();
       
$x = $ar->mul($ir);
       
$y = $br->mul($ir);
       
$this->assertNotSame($x->hex(), $y->hex(), 'x != y');
       
$this->assertSame($a->hex(), $x->hex(), 'a * r * 1/r == a');
       
$this->assertSame($b->hex(), $y->hex(), 'b * r * 1/r == b');
       
// complements
       
$xc = $x->complement();
       
$yc = $y->complement();
       
$this->assertNotSame($xc->hex(), $yc->hex(), 'given (x != y): comp(x) != comp(y)');
       
$one = $this->one();
       
$this->assertSame($xc->add($x)->hex(), $one->hex(), 's + comp = 1 (mod L)');
       
$this->assertSame($yc->add($y)->hex(), $one->hex(), 's + comp = 1 (mod L)');
    }

    public function
one(): ScalarValue
   
{
        return new
ScalarValue(
            new
HiddenString("\x01" . str_repeat("\x00", 31))
        );
    }

    public function
zero(): ScalarValue
   
{
        return new
ScalarValue(
            new
HiddenString(str_repeat("\x00", 32))
        );
    }

   
/**
     * Based on the libsodium example
     *
     * @link https://libsodium.gitbook.io/doc/advanced/point-arithmetic/ristretto#example
     * @throws Exception
     * @throws SodiumException
     */
   
public function testTwoPartyComputation(): void
   
{
       
$x = random_bytes(64);
       
$px = GroupElement::fromHash($x);
       
$r = ScalarValue::random();
       
$gr = $r->multBase();
       
$a = $px->add($gr);

       
$k = ScalarValue::random();
       
$v = $k->multBase();
       
$b = $k->scalarPointMultiply($a);

       
$ir = $r->negate();
       
$vir = $v->scalarPointMultiply($ir);
       
$fx = $b->add($vir);

       
// If you knew px and k:
       
$pxk = $px->scalarPointMultiply($k);

       
$this->assertSame($fx->hex(), $pxk->hex(), 'Ristretto error');
    }

    public function
testScalarPointMultiply()
    {
       
$alice_sk1 = SecretKey::generate();
       
$alice_sk2 = SecretKey::generate();
       
$bob_sk1 = SecretKey::generate();
       
$bob_sk2 = SecretKey::generate();

       
$alice_pk1 = $alice_sk1->getPublicKey();
       
$alice_pk2 = $alice_sk2->getPublicKey();
       
$bob_pk1 = $bob_sk1->getPublicKey();
       
$bob_pk2 = $bob_sk2->getPublicKey();

       
$x0 = $alice_sk1->scalarPointMultiply($bob_pk1);
       
$y0 = $bob_sk1->scalarPointMultiply($alice_pk1);
       
$this->assertTrue($x0->equals($y0), 'scalar multiplication must be commutative');

       
$x1 = $alice_sk2->scalarPointMultiply($bob_pk1);
       
$y1 = $bob_sk1->scalarPointMultiply($alice_pk2);
       
$this->assertTrue($x1->equals($y1), 'scalar multiplication must be commutative');

       
$x2 = $alice_sk1->scalarPointMultiply($bob_pk2);
       
$y2 = $bob_sk2->scalarPointMultiply($alice_pk1);
       
$this->assertTrue($x2->equals($y2), 'scalar multiplication must be commutative');

       
$x3 = $alice_sk2->scalarPointMultiply($bob_pk2);
       
$y3 = $bob_sk2->scalarPointMultiply($alice_pk2);
       
$this->assertTrue($x3->equals($y3), 'scalar multiplication must be commutative');

       
$this->assertFalse($x0->equals($x1), 'must not arrive on same points');
       
$this->assertFalse($x0->equals($x2), 'must not arrive on same points');
       
$this->assertFalse($x0->equals($x3), 'must not arrive on same points');
       
$this->assertFalse($x1->equals($x2), 'must not arrive on same points');
       
$this->assertFalse($x1->equals($x3), 'must not arrive on same points');
       
$this->assertFalse($x2->equals($x3), 'must not arrive on same points');

       
$this->assertFalse($y0->equals($y1), 'must not arrive on same points');
       
$this->assertFalse($y0->equals($y2), 'must not arrive on same points');
       
$this->assertFalse($y0->equals($y3), 'must not arrive on same points');
       
$this->assertFalse($y1->equals($y2), 'must not arrive on same points');
       
$this->assertFalse($y1->equals($y3), 'must not arrive on same points');
       
$this->assertFalse($y2->equals($y3), 'must not arrive on same points');
    }
}