Make WordPress Core

Ticket #39309: 39309.patch

File 39309.patch, 441.3 KB (added by paragoninitiativeenterprises, 10 years ago)

First round of Ed25519 verification

  • wp-includes/sodium_compat/LICENSE

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
     1/*
     2 * ISC License
     3 *
     4 * Copyright (c) 2016-2017
     5 * Paragon Initiative Enterprises <security at paragonie dot com>
     6 *
     7 * Copyright (c) 2013-2017
     8 * Frank Denis <j at pureftpd dot org>
     9 *
     10 * Permission to use, copy, modify, and/or distribute this software for any
     11 * purpose with or without fee is hereby granted, provided that the above
     12 * copyright notice and this permission notice appear in all copies.
     13 *
     14 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     15 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     16 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     17 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     18 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     19 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     20 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     21 */
     22 No newline at end of file
  • wp-includes/sodium_compat/composer.json

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
     1{
     2  "name": "paragonie/sodium_compat",
     3  "description": "Pure PHP implementation of libsodium; uses the PHP extension if it exists",
     4  "keywords": ["PHP", "cryptography", "elliptic curve", "side-channel resistant"],
     5  "license": "ISC",
     6  "authors": [
     7    {
     8      "name": "Paragon Initiative Enterprises",
     9      "email": "security@paragonie.com"
     10    },
     11    {
     12      "name": "Frank Denis",
     13      "email": "jedisct1@pureftpd.org"
     14    }
     15  ],
     16  "autoload": {
     17    "files": ["autoload.php"]
     18  },
     19  "require": {
     20    "php": "^5.2.4|^5.3|^5.4|^5.5|^5.6|^7",
     21    "paragonie/random_compat": "^1|^2"
     22  },
     23  "require-dev": {
     24    "phpunit/phpunit": "*"
     25  }
     26}
     27 No newline at end of file
  • wp-includes/sodium_compat/src/Core/Poly1305.php

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
     1<?php
     2
     3/**
     4 * Class ParagonIE_Sodium_Core_Poly1305
     5 */
     6abstract class ParagonIE_Sodium_Core_Poly1305 extends ParagonIE_Sodium_Core_Util
     7{
     8    const BLOCK_SIZE = 16;
     9
     10    /**
     11     * @param string $m
     12     * @param string $key
     13     * @return string
     14     */
     15    public static function onetimeauth($m, $key)
     16    {
     17        if (self::strlen($key) < 32) {
     18            throw new InvalidArgumentException(
     19                'Key must be 32 bytes long.'
     20            );
     21        }
     22        $state = new ParagonIE_Sodium_Core_Poly1305_State(
     23            self::substr($key, 0, 32)
     24        );
     25        return $state->update($m)->finish();
     26    }
     27
     28    /**
     29     * @param string $mac
     30     * @param string $m
     31     * @param string $key
     32     * @return bool
     33     */
     34    public static function onetimeauth_verify($mac, $m, $key)
     35    {
     36        if (self::strlen($key) < 32) {
     37            throw new InvalidArgumentException(
     38                'Key must be 32 bytes long.'
     39            );
     40        }
     41        $state = new ParagonIE_Sodium_Core_Poly1305_State(
     42            self::substr($key, 0, 32)
     43        );
     44        $calc = $state->update($m)->finish();
     45        return self::verify_16($calc, $mac);
     46    }
     47}
  • wp-includes/sodium_compat/tests/unit/SipHashTest.php

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
     1<?php
     2
     3class SipHashTest extends PHPUnit_Framework_TestCase
     4{
     5    public function setUp()
     6    {
     7        ParagonIE_Sodium_Compat::$disableFallbackForUnitTests = true;
     8    }
     9
     10    /**
     11     * @covers ParagonIE_Sodium_Core_SipHash::add()
     12     */
     13    public function testAdd()
     14    {
     15        if (PHP_INT_SIZE === 4) {
     16            $this->markTestSkipped('Test should be performed on a 64-bit OS');
     17            return;
     18        }
     19
     20        $vectors = array(
     21            array(
     22                0x0123456789abcdef,
     23                0x456789abcdef0123,
     24                0x468acf13579acf12
     25            ),
     26            array(
     27                0x0000000100000000,
     28                0x0000000000000100,
     29                0x0000000100000100
     30            ),
     31            array(
     32                0x0000000100000000,
     33                0x0000000000000100,
     34                0x0000000100000100
     35            ),
     36            array(
     37                0x0fffffffffffffff,
     38                0x0000000000000001,
     39                0x1000000000000000
     40            )
     41        );
     42        foreach ($vectors as $v) {
     43            list($a, $b, $c) = $v;
     44            # $this->assertSame($c, PHP_INT_MAX & ($a + $b));
     45
     46            $sA = array(
     47                $a >> 32,
     48                $a & 0xffffffff
     49            );
     50            $sB = array(
     51                $b >> 32,
     52                $b & 0xffffffff
     53            );
     54            $sC = array(
     55                ($c >> 32) & 0xffffffff,
     56                $c & 0xffffffff
     57            );
     58            $this->assertSame(
     59                $sC,
     60                ParagonIE_Sodium_Core_SipHash::add($sA, $sB)
     61            );
     62        }
     63    }
     64
     65    /**
     66     * @covers ParagonIE_Sodium_Core_SipHash::rotl_64()
     67     */
     68    public function testRotl64()
     69    {
     70        $this->assertSame(
     71            array(0x00010000, 0x00000000),
     72            ParagonIE_Sodium_Core_SipHash::rotl_64(0x00000001, 0x00000000, 16),
     73            'rotl_64 by 16'
     74        );
     75        $this->assertSame(
     76            array(0x80000000, 0x00000000),
     77            ParagonIE_Sodium_Core_SipHash::rotl_64(0x00000001, 0x00000000, 31),
     78            'rotl_64 by 31'
     79        );
     80        $this->assertSame(
     81            array(0x80000000, 0x00000000),
     82            ParagonIE_Sodium_Core_SipHash::rotl_64(0x00000001, 0x00000000, 95),
     83            'rotl_64 by 95 (reduce to 31)'
     84        );
     85        $this->assertSame(
     86            array(0x00000000, 0x00000001),
     87            ParagonIE_Sodium_Core_SipHash::rotl_64(0x00000001, 0x00000000, 32),
     88            'rotl_64 by 32'
     89        );
     90        $this->assertSame(
     91            array(0x00000000, 0x00000008),
     92            ParagonIE_Sodium_Core_SipHash::rotl_64(0x00000001, 0x00000000, 35),
     93            'rotl_64 by 35'
     94        );
     95        $this->assertSame(
     96            array(0x00000000, 0x80000000),
     97            ParagonIE_Sodium_Core_SipHash::rotl_64(0x00000001, 0x00000000, 63),
     98            'rotl_64 by 63'
     99        );
     100        $this->assertSame(
     101            array(0x00000001, 0x00000000),
     102            ParagonIE_Sodium_Core_SipHash::rotl_64(0x00000001, 0x00000000, 64),
     103            'rotl_64 by 64'
     104        );
     105        $this->assertSame(
     106            array(0x7DDF575A, 0x3BD5BD5B),
     107            ParagonIE_Sodium_Core_SipHash::rotl_64(0xDEADBEEF, 0xABAD1DEA, 17),
     108            'rotl_64 by 64'
     109        );
     110    }
     111
     112    /**
     113     *
     114     */
     115    public function testCryptoShorthash()
     116    {
     117        $message = 'this is just a test message';
     118        $key = str_repeat("\x80", 16);
     119
     120        $this->assertSame(
     121            '3f188259b01151a7',
     122            bin2hex(ParagonIE_Sodium_Compat::crypto_shorthash($message, $key))
     123        );
     124    }
     125}
     126 No newline at end of file
  • wp-includes/sodium_compat/tests/unit/Poly1305Test.php

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
     1<?php
     2
     3class Poly1305Test extends PHPUnit_Framework_TestCase
     4{
     5    public function setUp()
     6    {
     7        ParagonIE_Sodium_Compat::$disableFallbackForUnitTests = true;
     8    }
     9
     10    /**
     11     * @covers ParagonIE_Sodium_Core_Poly1305::onetimeauth()
     12     * @ref https://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-04#page-12
     13     */
     14    public function testVectorA()
     15    {
     16        $msg = ParagonIE_Sodium_Core_Util::hex2bin('0000000000000000000000000000000000000000000000000000000000000000');
     17        $key = ParagonIE_Sodium_Core_Util::hex2bin('746869732069732033322d62797465206b657920666f7220506f6c7931333035');
     18        $this->assertSame(
     19            '49ec78090e481ec6c26b33b91ccc0307',
     20            bin2hex(ParagonIE_Sodium_Core_Poly1305::onetimeauth($msg, $key)),
     21            'crypto_onetimeauth is broken'
     22        );
     23    }
     24
     25    /**
     26     * @covers ParagonIE_Sodium_Core_Poly1305::onetimeauth()
     27     * @ref https://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-04#page-12
     28     */
     29    public function testVectorB()
     30    {
     31
     32        $msg = ParagonIE_Sodium_Core_Util::hex2bin('48656c6c6f20776f726c6421');
     33        $key = ParagonIE_Sodium_Core_Util::hex2bin('746869732069732033322d62797465206b657920666f7220506f6c7931333035');
     34        $this->assertSame(
     35            'a6f745008f81c916a20dcc74eef2b2f0',
     36            bin2hex(ParagonIE_Sodium_Core_Poly1305::onetimeauth($msg, $key)),
     37            'crypto_onetimeauth is broken'
     38        );
     39    }
     40
     41    /**
     42     * @covers ParagonIE_Sodium_Core_Poly1305::onetimeauth()
     43     *
     44     * A large message test vector.
     45     *
     46     * @ref https://github.com/jedisct1/libsodium/blob/master/test/default/onetimeauth2.c
     47     */
     48    public function testVectorC()
     49    {
     50
     51        $msg = ParagonIE_Sodium_Core_Util::intArrayToString(
     52            array(
     53                0x8e, 0x99, 0x3b, 0x9f, 0x48, 0x68, 0x12, 0x73, 0xc2, 0x96, 0x50, 0xba,
     54                0x32, 0xfc, 0x76, 0xce, 0x48, 0x33, 0x2e, 0xa7, 0x16, 0x4d, 0x96, 0xa4,
     55                0x47, 0x6f, 0xb8, 0xc5, 0x31, 0xa1, 0x18, 0x6a, 0xc0, 0xdf, 0xc1, 0x7c,
     56                0x98, 0xdc, 0xe8, 0x7b, 0x4d, 0xa7, 0xf0, 0x11, 0xec, 0x48, 0xc9, 0x72,
     57                0x71, 0xd2, 0xc2, 0x0f, 0x9b, 0x92, 0x8f, 0xe2, 0x27, 0x0d, 0x6f, 0xb8,
     58                0x63, 0xd5, 0x17, 0x38, 0xb4, 0x8e, 0xee, 0xe3, 0x14, 0xa7, 0xcc, 0x8a,
     59                0xb9, 0x32, 0x16, 0x45, 0x48, 0xe5, 0x26, 0xae, 0x90, 0x22, 0x43, 0x68,
     60                0x51, 0x7a, 0xcf, 0xea, 0xbd, 0x6b, 0xb3, 0x73, 0x2b, 0xc0, 0xe9, 0xda,
     61                0x99, 0x83, 0x2b, 0x61, 0xca, 0x01, 0xb6, 0xde, 0x56, 0x24, 0x4a, 0x9e,
     62                0x88, 0xd5, 0xf9, 0xb3, 0x79, 0x73, 0xf6, 0x22, 0xa4, 0x3d, 0x14, 0xa6,
     63                0x59, 0x9b, 0x1f, 0x65, 0x4c, 0xb4, 0x5a, 0x74, 0xe3, 0x55, 0xa5
     64            )
     65        );;
     66        $key = ParagonIE_Sodium_Core_Util::intArrayToString(
     67            array(
     68                0xee, 0xa6, 0xa7, 0x25, 0x1c, 0x1e, 0x72, 0x91, 0x6d, 0x11, 0xc2,
     69                0xcb, 0x21, 0x4d, 0x3c, 0x25, 0x25, 0x39, 0x12, 0x1d, 0x8e, 0x23,
     70                0x4e, 0x65, 0x2d, 0x65, 0x1f, 0xa4, 0xc8, 0xcf, 0xf8, 0x80
     71            )
     72        );
     73        $tag = ParagonIE_Sodium_Core_Util::intArrayToString(
     74            array(
     75                0xf3, 0xff, 0xc7, 0x70, 0x3f, 0x94, 0x00, 0xe5,
     76                0x2a, 0x7d, 0xfb, 0x4b, 0x3d, 0x33, 0x05, 0xd9
     77            )
     78        );
     79
     80        $this->assertSame(
     81            bin2hex($tag),
     82            bin2hex(ParagonIE_Sodium_Core_Poly1305::onetimeauth($msg, $key)),
     83            'crypto_onetimeauth is broken'
     84        );
     85        $this->assertTrue(
     86            ParagonIE_Sodium_Core_Poly1305::onetimeauth_verify($tag, $msg, $key),
     87            'crypto_onetimeauth_verify is broken'
     88        );
     89    }
     90
     91    /**
     92     * @covers ParagonIE_Sodium_Core_Poly1305::onetimeauth_verify()
     93     */
     94    public function testRandomVerify()
     95    {
     96        $msg = random_bytes(random_int(1, 1000));
     97        $key = random_bytes(32);
     98
     99        $mac = ParagonIE_Sodium_Core_Poly1305::onetimeauth($msg, $key);
     100        $this->assertTrue(
     101            ParagonIE_Sodium_Core_Poly1305::onetimeauth_verify($mac, $msg, $key),
     102            'crypto_onetimeauth_verify is broken'
     103        );
     104    }
     105}
     106 No newline at end of file
  • wp-includes/sodium_compat/tests/unit/Salsa20Test.php

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
     1<?php
     2
     3class Salsa20Test extends PHPUnit_Framework_TestCase
     4{
     5    public function setUp()
     6    {
     7        ParagonIE_Sodium_Compat::$disableFallbackForUnitTests = true;
     8    }
     9
     10    /**
     11     * @covers ParagonIE_Sodium_Core_Salsa20::rotate()
     12     */
     13    public function testRotate()
     14    {
     15        $this->assertEquals(
     16            0x00001000,
     17            ParagonIE_Sodium_Core_Salsa20::rotate(0x00000001, 12),
     18            'Left rotate by 12'
     19        );
     20
     21        $this->assertEquals(
     22            0x00002000,
     23            ParagonIE_Sodium_Core_Salsa20::rotate(0x00000001, 13),
     24            'Left rotate by 13'
     25        );
     26        $this->assertEquals(
     27            0x10000000,
     28            ParagonIE_Sodium_Core_Salsa20::rotate(0x00000001, 28),
     29            'Left rotate by 28'
     30        );
     31        $this->assertEquals(
     32            0x80000000,
     33            ParagonIE_Sodium_Core_Salsa20::rotate(0x00000001, 31),
     34            'Left rotate by 31'
     35        );
     36        $this->assertEquals(
     37            0x00000001,
     38            ParagonIE_Sodium_Core_Salsa20::rotate(0x00000001, 32),
     39            'Left rotate by 32'
     40        );
     41
     42        $this->assertEquals(
     43            0xf0001000,
     44            ParagonIE_Sodium_Core_Salsa20::rotate(0x000f0001, 12),
     45            'Left rotate by 12'
     46        );
     47
     48        $this->assertEquals(
     49            0xe0002001,
     50            ParagonIE_Sodium_Core_Salsa20::rotate(0x000f0001, 13),
     51            'Left rotate by 13'
     52        );
     53
     54        $this->assertEquals(
     55            0xc0004003,
     56            ParagonIE_Sodium_Core_Salsa20::rotate(0x000f0001, 14),
     57            'Left rotate by 14'
     58        );
     59
     60        $this->assertEquals(
     61            0x80008007,
     62            ParagonIE_Sodium_Core_Salsa20::rotate(0x000f0001, 15),
     63            'Left rotate by 15'
     64        );
     65
     66        $this->assertEquals(
     67            0x0001000f,
     68            ParagonIE_Sodium_Core_Salsa20::rotate(0x000f0001, 16),
     69            'Left rotate by 16'
     70        );
     71    }
     72
     73    /**
     74     * @covers ParagonIE_Sodium_Core_Salsa20::salsa20()
     75     */
     76    public function testVectors()
     77    {
     78        $key = "\x80" . str_repeat("\x00", 31);
     79        $iv = str_repeat("\x00", 8);
     80
     81        $output = ParagonIE_Sodium_Core_Salsa20::salsa20(512, $iv, $key);
     82
     83        $this->assertSame(
     84            'E3BE8FDD8BECA2E3EA8EF9475B29A6E7' .
     85            '003951E1097A5C38D23B7A5FAD9F6844' .
     86            'B22C97559E2723C7CBBD3FE4FC8D9A07' .
     87            '44652A83E72A9C461876AF4D7EF1A117',
     88            strtoupper(
     89                bin2hex(
     90                    ParagonIE_Sodium_Core_Util::substr($output, 0, 64)
     91                )
     92            ),
     93            'Test vector #1 failed!'
     94        );
     95
     96        $this->assertSame(
     97            '57BE81F47B17D9AE7C4FF15429A73E10' .
     98            'ACF250ED3A90A93C711308A74C6216A9' .
     99            'ED84CD126DA7F28E8ABF8BB63517E1CA' .
     100            '98E712F4FB2E1A6AED9FDC73291FAA17',
     101            strtoupper(
     102                bin2hex(
     103                    ParagonIE_Sodium_Core_Util::substr($output, 192, 64)
     104                )
     105            ),
     106            'Test vector #1 failed!'
     107        );
     108    }
     109
     110    /**
     111     * @covers ParagonIE_Sodium_Core_Salsa20::core_salsa20()
     112     */
     113    public function testCoreSalsa20()
     114    {
     115        $key = random_bytes(32);
     116        $iv = random_bytes(8);
     117        $outA = ParagonIE_Sodium_Core_Salsa20::salsa20(192, $iv, $key);
     118
     119        // First block
     120        $outB = ParagonIE_Sodium_Core_Salsa20::core_salsa20($iv . str_repeat("\x00", 8), $key);
     121        $this->assertSame(
     122            bin2hex(
     123                ParagonIE_Sodium_Core_Util::substr($outA, 0, 64)
     124            ),
     125            bin2hex($outB)
     126        );
     127
     128        // Second block
     129        $outC = ParagonIE_Sodium_Core_Salsa20::core_salsa20($iv . "\x01" . str_repeat("\x00", 7), $key);
     130        $this->assertSame(
     131            bin2hex(
     132                ParagonIE_Sodium_Core_Util::substr($outA, 64, 64)
     133            ),
     134            bin2hex($outC)
     135        );
     136
     137        // Third block
     138        $outD = ParagonIE_Sodium_Core_Salsa20::core_salsa20($iv . "\x02" . str_repeat("\x00", 7), $key);
     139        $this->assertSame(
     140            bin2hex(
     141                ParagonIE_Sodium_Core_Util::substr($outA, 128, 64)
     142            ),
     143            bin2hex($outD)
     144        );
     145    }
     146}
  • wp-admin/includes/class-wp-upgrader.php

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
    5050 */
    5151class WP_Upgrader {
    5252
     53    const ED25519_PUBLIC_KEY = '4d6236cc44829b2f96a26d905aec92162077ef5aa7e0a4e2a6d251258dc83bd1';
     54
    5355        /**
    5456         * The error/notification strings used to update the user on the progress.
    5557         *
     
    274276
    275277                $this->skin->feedback('downloading_package', $package);
    276278
    277                 $download_file = download_url($package);
     279                $download_file = download_url($package, 300, self::ED25519_PUBLIC_KEY);
     280                if ( is_wp_error($download_file) ) {
     281            if ($download_file->get_error_code() === 'ed25519_mismatch') {
     282                $package .= '?ed25519failed=1';
     283                // Try again without Ed25519 verification. Remove this silent fallback in the next version.
     284                $download_file = download_url($package);
     285            }
     286        }
    278287
    279288                if ( is_wp_error($download_file) )
    280289                        return new WP_Error('download_failed', $this->strings['download_failed'], $download_file->get_error_message());
  • wp-includes/sodium_compat/README.md

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
     1# Sodium Compat
     2
     3[![Build Status](https://travis-ci.org/paragonie/sodium_compat.svg?branch=master)](https://travis-ci.org/paragonie/sodium_compat)
     4[![Latest Stable Version](https://poser.pugx.org/paragonie/sodium_compat/v/stable)](https://packagist.org/packages/paragonie/sodium_compat)
     5[![Latest Unstable Version](https://poser.pugx.org/paragonie/sodium_compat/v/unstable)](https://packagist.org/packages/paragonie/sodium_compat)
     6[![License](https://poser.pugx.org/paragonie/sodium_compat/license)](https://packagist.org/packages/paragonie/sodium_compat)
     7
     8Sodium Compat is a pure PHP polyfill for the Sodium cryptography library
     9(libsodium), otherwise [available in PECL](https://pecl.php.net/package/libsodium).
     10
     11This library tentativeley supports PHP 5.2.4 - 7.x (latest), but officially
     12only supports [non-EOL'd versions of PHP](https://secure.php.net/supported-versions.php).
     13
     14If you have the PHP extension installed, Sodium Compat will opportunistically
     15and transparently use the PHP extension instead of our implementation.
     16
     17## IMPORTANT!
     18
     19### ![Danger: Experimental](https://camo.githubusercontent.com/275bc882f21b154b5537b9c123a171a30de9e6aa/68747470733a2f2f7261772e6769746875622e636f6d2f63727970746f7370686572652f63727970746f7370686572652f6d61737465722f696d616765732f6578706572696d656e74616c2e706e67)
     20
     21This is an **experimental** cryptography library. It has not been formally
     22audited by an independent third party that specializes in cryptography or
     23cryptanalysis.
     24
     25Until it has received a clean bill of health from independent computer security
     26experts, **use this library at your own risk.**
     27
     28# Installing Sodium Compat
     29
     30If you're using Composer:
     31
     32```bash
     33composer require paragonie/sodium_compat
     34```
     35
     36If you're not using Composer, download a [release tarball](https://github.com/paragonie/sodium_compat/releases)
     37(which should be signed with [our GnuPG public key](https://paragonie.com/static/gpg-public-key.txt)), extract
     38its contents, then include our `autoload.php` script in your project.
     39
     40```php
     41<?php
     42require_once "/path/to/sodium_compat/autoload.php";
     43```
     44
     45# Using Sodium Compat
     46
     47## True Polyfill
     48
     49If you're using PHP 5.3.0 or newer and do not have the PECL extension installed,
     50you can just use the [standard ext/sodium API features as-is](https://paragonie.com/book/pecl-libsodium)
     51and the polyfill will work its magic.
     52
     53```php
     54<?php
     55require_once "/path/to/sodium_compat/autoload.php";
     56
     57$alice_kp = \Sodium\crypto_sign_keypair();
     58$alice_sk = \Sodium\crypto_sign_secretkey($alice_kp);
     59$alice_pk = \Sodium\crypto_sign_publickey($alice_kp);
     60
     61$message = 'This is a test message.';
     62$signature = \Sodium\crypto_sign_detached($message, $alice_sk);
     63if (\Sodium\crypto_sign_verify_detached($signature, $message, $alice_pk)) {
     64    echo 'OK', PHP_EOL;
     65} else {
     66    throw new Exception('Invalid signature');
     67}
     68```
     69
     70The polyfill does not expose this API on PHP < 5.3, or if you have the PHP
     71extension installed already.
     72
     73## General-Use Polyfill
     74
     75If your users are on PHP < 5.3, or you want to write code that will work
     76whether or not the PECL extension is available, you'll want to use the
     77**`ParagonIE_Sodium_Compat`** class for most of your libsodium needs.
     78
     79The above example, written for general use:
     80
     81```php
     82<?php
     83require_once "/path/to/sodium_compat/autoload.php";
     84
     85$alice_kp = ParagonIE_Sodium_Compat::crypto_sign_keypair();
     86$alice_sk = ParagonIE_Sodium_Compat::crypto_sign_secretkey($alice_kp);
     87$alice_pk = ParagonIE_Sodium_Compat::crypto_sign_publickey($alice_kp);
     88
     89$message = 'This is a test message.';
     90$signature = ParagonIE_Sodium_Compat::crypto_sign_detached($message, $alice_sk);
     91if (ParagonIE_Sodium_Compat::crypto_sign_verify_detached($signature, $message, $alice_pk)) {
     92    echo 'OK', PHP_EOL;
     93} else {
     94    throw new Exception('Invalid signature');
     95}
     96```
     97
     98Generally: If you replace `\Sodium\ ` with `ParagonIE_Sodium_Compat::`, any
     99code already written for the libsodium PHP extension should work with our
     100polyfill without additional code changes.
     101
     102To learn how to use Libsodium, read [*Using Libsodium in PHP Projects*](https://paragonie.com/book/pecl-libsodium).
     103
     104## API Coverage
     105
     106* Mainline NaCl Features
     107    * `crypto_auth()`
     108    * `crypto_auth_verify()`
     109    * `crypto_box()`
     110    * `crypto_box_open()`
     111    * `crypto_scalarmult()`
     112    * `crypto_secretbox()`
     113    * `crypto_secretbox_open()`
     114    * `crypto_sign()`
     115    * `crypto_sign_open()`
     116* PECL Libsodium Features
     117    * `crypto_box_seal()`
     118    * `crypto_box_seal_open()`
     119    * `crypto_generichash()`
     120    * `crypto_generichash_init()`
     121    * `crypto_generichash_update()`
     122    * `crypto_generichash_final()`
     123    * `crypto_kx()`
     124    * `crypto_shorthash()`
     125    * `crypto_sign_detached()`
     126    * `crypto_sign_verify_detached()`
     127    * For advanced users only:
     128        * `crypto_stream()`
     129        * `crypto_stream_xor()`
     130    * Other utilities (e.g. `crypto_*_keypair()`)
     131
     132### Features Excluded from this Polyfill
     133
     134* `\Sodium\memzero()` - Although we expose this API endpoint, it's a NOP. We can't
     135  reliably zero buffers from PHP.
     136* `\Sodium\crypto_pwhash()` - It's not feasible to polyfill scrypt or Argon2 into PHP and get
     137  reasonable performance. Users would feel motivated to select parameters that downgrade
     138  security to avoid denial of service (DoS) attacks.
     139 
     140  The only winning move is not to play.
  • wp-includes/sodium_compat/src/Core/Poly1305/State.php

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
     1<?php
     2
     3/**
     4 * Class ParagonIE_Sodium_Core_Poly1305_State
     5 */
     6class ParagonIE_Sodium_Core_Poly1305_State extends ParagonIE_Sodium_Core_Util
     7{
     8    /**
     9     * @var int[]
     10     */
     11    protected $buffer = array();
     12
     13    /**
     14     * @var bool
     15     */
     16    protected $final = false;
     17
     18    /**
     19     * @var int[]
     20     */
     21    public $h;
     22
     23    /**
     24     * @var int
     25     */
     26    protected $leftover = 0;
     27
     28    /**
     29     * @var int[]
     30     */
     31    public $r;
     32
     33    /**
     34     * @var int[]
     35     */
     36    public $pad;
     37
     38    /**
     39     * ParagonIE_Sodium_Core_Poly1305_State constructor.
     40     * @param string $key
     41     */
     42    public function __construct($key = '')
     43    {
     44        if (self::strlen($key) < 32) {
     45            throw new InvalidArgumentException(
     46                'Poly1305 requires a 32-byte key'
     47            );
     48        }
     49        /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */
     50        $this->r = array(
     51            (self::load_4(self::substr($key,  0, 4))     ) & 0x3ffffff,
     52            (self::load_4(self::substr($key,  3, 4)) >> 2) & 0x3ffff03,
     53            (self::load_4(self::substr($key,  6, 4)) >> 4) & 0x3ffc0ff,
     54            (self::load_4(self::substr($key,  9, 4)) >> 6) & 0x3f03fff,
     55            (self::load_4(self::substr($key, 12, 4)) >> 8) & 0x00fffff
     56        );
     57
     58        /* h = 0 */
     59        $this->h = array(0, 0, 0, 0, 0);
     60
     61        /* save fpad for later */
     62        $this->pad = array(
     63            self::load_4(self::substr($key, 16, 4)),
     64            self::load_4(self::substr($key, 20, 4)),
     65            self::load_4(self::substr($key, 24, 4)),
     66            self::load_4(self::substr($key, 28, 4)),
     67        );
     68
     69        $this->leftover = 0;
     70        $this->final = false;
     71    }
     72
     73    /**
     74     * @param string $message
     75     * @return self
     76     */
     77    public function update($message = '')
     78    {
     79        $bytes = self::strlen($message);
     80
     81        /* handle leftover */
     82        if ($this->leftover) {
     83            $want = ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE - $this->leftover;
     84            if ($want > $bytes) {
     85                $want = $bytes;
     86            }
     87            for ($i = 0; $i < $want; ++$i) {
     88                $mi = self::chrToInt($message[$i]);
     89                $this->buffer[$this->leftover + $i] = $mi;
     90            }
     91            // We snip off the leftmost bytes.
     92            $message = self::substr($message, $want);
     93            $bytes = self::strlen($message);
     94            $this->leftover += $want;
     95            if ($this->leftover < ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE) {
     96                // We still don't have enough to run $this->blocks()
     97                return $this;
     98            }
     99
     100            $this->blocks(
     101                static::intArrayToString($this->buffer),
     102                ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE
     103            );
     104            $this->leftover = 0;
     105        }
     106
     107        /* process full blocks */
     108        if ($bytes >= ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE) {
     109            $want = $bytes & ~(ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE - 1);
     110            if ($want >= ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE) {
     111                $block = self::substr($message, 0, $want);
     112                if (self::strlen($block) >= ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE) {
     113                    $this->blocks($block, $want);
     114                    $message = self::substr($message, $want);
     115                    $bytes = self::strlen($message);
     116                }
     117            }
     118        }
     119
     120        /* store leftover */
     121        if ($bytes) {
     122            for ($i = 0; $i < $bytes; ++$i) {
     123                $mi = self::chrToInt($message[$i]);
     124                $this->buffer[$this->leftover + $i] = $mi;
     125            }
     126            $this->leftover = (int) $this->leftover + $bytes;
     127        }
     128        return $this;
     129    }
     130
     131    /**
     132     * @param string $message
     133     * @param int $bytes
     134     * @return self
     135     */
     136    public function blocks($message, $bytes)
     137    {
     138        if (self::strlen($message) < 16) {
     139            $message = str_pad($message, 16, "\x00", STR_PAD_RIGHT);
     140        }
     141        $hibit = $this->final ? 0 : 1 << 24; /* 1 << 128 */
     142        $r0 = (int) $this->r[0];
     143        $r1 = (int) $this->r[1];
     144        $r2 = (int) $this->r[2];
     145        $r3 = (int) $this->r[3];
     146        $r4 = (int) $this->r[4];
     147
     148        $s1 = $r1 * 5;
     149        $s2 = $r2 * 5;
     150        $s3 = $r3 * 5;
     151        $s4 = $r4 * 5;
     152
     153        $h0 = $this->h[0];
     154        $h1 = $this->h[1];
     155        $h2 = $this->h[2];
     156        $h3 = $this->h[3];
     157        $h4 = $this->h[4];
     158
     159        while ($bytes >= ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE) {
     160            /* h += m[i] */
     161            $h0 +=  self::load_4(self::substr($message,  0, 4))       & 0x3ffffff;
     162            $h1 += (self::load_4(self::substr($message,  3, 4)) >> 2) & 0x3ffffff;
     163            $h2 += (self::load_4(self::substr($message,  6, 4)) >> 4) & 0x3ffffff;
     164            $h3 += (self::load_4(self::substr($message,  9, 4)) >> 6) & 0x3ffffff;
     165            $h4 += (self::load_4(self::substr($message, 12, 4)) >> 8) | $hibit;
     166
     167            /* h *= r */
     168            $d0 = (
     169                ($h0 * $r0) +
     170                ($h1 * $s4) +
     171                ($h2 * $s3) +
     172                ($h3 * $s2) +
     173                ($h4 * $s1)
     174            );
     175            $d1 = (
     176                ($h0 * $r1) +
     177                ($h1 * $r0) +
     178                ($h2 * $s4) +
     179                ($h3 * $s3) +
     180                ($h4 * $s2)
     181            );
     182
     183            $d2 = (
     184                ($h0 * $r2) +
     185                ($h1 * $r1) +
     186                ($h2 * $r0) +
     187                ($h3 * $s4) +
     188                ($h4 * $s3)
     189            );
     190
     191            $d3 = (
     192                ($h0 * $r3) +
     193                ($h1 * $r2) +
     194                ($h2 * $r1) +
     195                ($h3 * $r0) +
     196                ($h4 * $s4)
     197            );
     198
     199            $d4 = (
     200                ($h0 * $r4) +
     201                ($h1 * $r3) +
     202                ($h2 * $r2) +
     203                ($h3 * $r1) +
     204                ($h4 * $r0)
     205            );
     206
     207            /* (partial) h %= p */
     208                                 $c = $d0 >> 26; $h0 = $d0 & 0x3ffffff;
     209            $d1 += $c;           $c = $d1 >> 26; $h1 = $d1 & 0x3ffffff;
     210            $d2 += $c;           $c = $d2 >> 26; $h2 = $d2 & 0x3ffffff;
     211            $d3 += $c;           $c = $d3 >> 26; $h3 = $d3 & 0x3ffffff;
     212            $d4 += $c;           $c = $d4 >> 26; $h4 = $d4 & 0x3ffffff;
     213            $h0 += (int) $c * 5; $c = $h0 >> 26; $h0 &= 0x3ffffff;
     214            $h1 += $c;
     215
     216            // Chop off the left 32 bytes.
     217            $message = self::substr(
     218                $message,
     219                ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE
     220            );
     221            $bytes -= ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE;
     222        }
     223
     224        $this->h = array(
     225            (int) $h0 & 0xffffffff,
     226            (int) $h1 & 0xffffffff,
     227            (int) $h2 & 0xffffffff,
     228            (int) $h3 & 0xffffffff,
     229            (int) $h4 & 0xffffffff
     230        );
     231        return $this;
     232    }
     233
     234    /**
     235     * @return string
     236     */
     237    public function finish()
     238    {
     239        /* process the remaining block */
     240        if ($this->leftover) {
     241            $i = $this->leftover;
     242            $this->buffer[$i++] = 1;
     243            for (; $i < ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE; ++$i) {
     244                $this->buffer[$i] = 0;
     245            }
     246            $this->final = true;
     247            $this->blocks(
     248                self::substr(
     249                    static::intArrayToString($this->buffer),
     250                    0,
     251                    ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE
     252                ),
     253                ParagonIE_Sodium_Core_Poly1305::BLOCK_SIZE
     254            );
     255        }
     256
     257        $h0 = (int) $this->h[0];
     258        $h1 = (int) $this->h[1];
     259        $h2 = (int) $this->h[2];
     260        $h3 = (int) $this->h[3];
     261        $h4 = (int) $this->h[4];
     262
     263                       $c = $h1 >> 26; $h1 &= 0x3ffffff;
     264        $h2 += $c;     $c = $h2 >> 26; $h2 &= 0x3ffffff;
     265        $h3 += $c;     $c = $h3 >> 26; $h3 &= 0x3ffffff;
     266        $h4 += $c;     $c = $h4 >> 26; $h4 &= 0x3ffffff;
     267        $h0 += $c * 5; $c = $h0 >> 26; $h0 &= 0x3ffffff;
     268        $h1 += $c;
     269
     270        /* compute h + -p */
     271        $g0 = $h0 +  5; $c = $g0 >> 26; $g0 &= 0x3ffffff;
     272        $g1 = $h1 + $c; $c = $g1 >> 26; $g1 &= 0x3ffffff;
     273        $g2 = $h2 + $c; $c = $g2 >> 26; $g2 &= 0x3ffffff;
     274        $g3 = $h3 + $c; $c = $g3 >> 26; $g3 &= 0x3ffffff;
     275        $g4 = ($h4 + $c - (1 << 26)) & 0xffffffff;
     276
     277        /* select h if h < p, or h + -p if h >= p */
     278        $mask = ($g4 >> 31) - 1;
     279
     280        $g0 &= $mask;
     281        $g1 &= $mask;
     282        $g2 &= $mask;
     283        $g3 &= $mask;
     284        $g4 &= $mask;
     285
     286        $mask = ~$mask & 0xffffffff;
     287        $h0 = ($h0 & $mask) | $g0;
     288        $h1 = ($h1 & $mask) | $g1;
     289        $h2 = ($h2 & $mask) | $g2;
     290        $h3 = ($h3 & $mask) | $g3;
     291        $h4 = ($h4 & $mask) | $g4;
     292
     293        /* h = h % (2^128) */
     294        $h0 = (($h0      ) | ($h1 << 26)) & 0xffffffff;
     295        $h1 = (($h1 >>  6) | ($h2 << 20)) & 0xffffffff;
     296        $h2 = (($h2 >> 12) | ($h3 << 14)) & 0xffffffff;
     297        $h3 = (($h3 >> 18) | ($h4 <<  8)) & 0xffffffff;
     298
     299        /* mac = (h + pad) % (2^128) */
     300        $f = ($h0 + $this->pad[0]);
     301        $h0 = (int) $f;
     302        $f = ($h1 + $this->pad[1] + ($f >> 32));
     303        $h1 = (int) $f;
     304        $f = ($h2 + $this->pad[2] + ($f >> 32));
     305        $h2 = (int) $f;
     306        $f = ($h3 + $this->pad[3] + ($f >> 32));
     307        $h3 = (int) $f;
     308
     309        return self::store32_le($h0 & 0xffffffff) .
     310            self::store32_le($h1 & 0xffffffff) .
     311            self::store32_le($h2 & 0xffffffff) .
     312            self::store32_le($h3 & 0xffffffff);
     313    }
     314}
  • wp-includes/sodium_compat/src/Core/Util.php

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
     1<?php
     2
     3/**
     4 * Class ParagonIE_Sodium_Core_Util
     5 */
     6abstract class ParagonIE_Sodium_Core_Util
     7{
     8    /**
     9     * Load a 3 character substring into an integer
     10     *
     11     * @param $string
     12     * @return int;
     13     */
     14    public static function load_3($string)
     15    {
     16        $result = self::chrToInt($string[0]);
     17        $result |= self::chrToInt($string[1]) << 8;
     18        $result |= self::chrToInt($string[2]) << 16;
     19        return $result & 0xffffff;
     20    }
     21
     22    /**
     23     * Load a 4 character substring into an integer
     24     *
     25     * @param $string
     26     * @return int
     27     * @throws Exception
     28     */
     29    public static function load_4($string)
     30    {
     31        if (self::strlen($string) < 4) {
     32            throw new Exception('String must be 4 bytes or more; ' . self::strlen($string) . ' given.');
     33        }
     34        $result = self::chrToInt($string[0]) & 0xff;
     35        $result |= (self::chrToInt($string[1]) & 0xff) << 8;
     36        $result |= (self::chrToInt($string[2]) & 0xff) << 16;
     37        $result |= (self::chrToInt($string[3]) & 0xff) << 24;
     38        return $result & 0xffffffff;
     39    }
     40
     41    /**
     42     * Store a 24-bit integer into a string, treating it as big-endian.
     43     *
     44     * @param $int
     45     * @return string
     46     */
     47    public static function store_3($int)
     48    {
     49        return self::intToChr(($int >> 16)    & 0xff) .
     50            self::intToChr(($int >> 8)     & 0xff) .
     51            self::intToChr( $int           & 0xff);
     52    }
     53
     54    /**
     55     * Store a 32-bit integer into a string, treating it as big-endian.
     56     *
     57     * @param $int
     58     * @return string
     59     */
     60    public static function store_4($int)
     61    {
     62        return self::intToChr(($int >> 24) & 0xff) .
     63            self::intToChr(($int >> 16)    & 0xff) .
     64            self::intToChr(($int >> 8)     & 0xff) .
     65            self::intToChr( $int           & 0xff);
     66    }
     67
     68    /**
     69     * Store a 32-bit integer into a string, treating it as little-endian.
     70     *
     71     * @param $int
     72     * @return string
     73     */
     74    public static function store32_le($int)
     75    {
     76        return self::intToChr($int      & 0xff) .
     77            self::intToChr(($int >> 8)  & 0xff) .
     78            self::intToChr(($int >> 16) & 0xff) .
     79            self::intToChr(($int >> 24) & 0xff);
     80    }
     81
     82    /**
     83     * Convert a binary string into a hexadecimal string without cache-timing
     84     * leaks
     85     *
     86     * @param string $bin_string (raw binary)
     87     * @return string
     88     */
     89    public static function bin2hex($bin_string)
     90    {
     91        $hex = '';
     92        $len = self::strlen($bin_string);
     93        for ($i = 0; $i < $len; ++$i) {
     94            $chunk = unpack('C', self::substr($bin_string, $i, 2));
     95            $c = $chunk[1] & 0xf;
     96            $b = $chunk[1] >> 4;
     97            $hex .= pack(
     98                'CC',
     99                (87 + $b + ((($b - 10) >> 8) & ~38)),
     100                (87 + $c + ((($c - 10) >> 8) & ~38))
     101            );
     102        }
     103        return $hex;
     104    }
     105
     106    /**
     107     * Convert a binary string into a hexadecimal string without cache-timing
     108     * leaks, returning uppercase letters (as per RFC 4648)
     109     *
     110     * @param string $bin_string (raw binary)
     111     * @return string
     112     */
     113    public static function bin2hexUpper($bin_string)
     114    {
     115        $hex = '';
     116        $len = self::strlen($bin_string);
     117        for ($i = 0; $i < $len; ++$i) {
     118            $chunk = unpack('C', self::substr($bin_string, $i, 2));
     119            $c = $chunk[1] & 0xf;
     120            $b = $chunk[1] >> 4;
     121            $hex .= pack(
     122                'CC',
     123                (55 + $b + ((($b - 10) >> 8) & ~6)),
     124                (55 + $c + ((($c - 10) >> 8) & ~6))
     125            );
     126        }
     127        return $hex;
     128    }
     129
     130    /**
     131     * Compares two strings.
     132     *
     133     * @param string $left
     134     * @param string $right
     135     * @param int $len
     136     * @return int
     137     */
     138    public static function compare($left, $right, $len = null)
     139    {
     140        $leftLen = self::strlen($left);
     141        $rightLen = self::strlen($right);
     142        if ($len === null) {
     143            $len = max($leftLen, $rightLen);
     144            $left = str_pad($left, $len, "\x00", STR_PAD_RIGHT);
     145            $right = str_pad($right, $len, "\x00", STR_PAD_RIGHT);
     146        }
     147
     148        $gt = 0;
     149        $eq = 1;
     150        $i = $len;
     151        while ($i !== 0) {
     152            --$i;
     153            $gt |= ((self::chrToInt($right[$i]) - self::chrToInt($left[$i])) >> 8) & $eq;
     154            $eq &= ((self::chrToInt($right[$i]) ^ self::chrToInt($left[$i])) - 1) >> 8;
     155        }
     156        return ($gt + $gt + $eq) - 1;
     157    }
     158
     159    /**
     160     * @param string $left
     161     * @param string $right
     162     * @return int
     163     */
     164    public static function memcmp($left, $right)
     165    {
     166        if (hash_equals($left, $right)) {
     167            return 0;
     168        }
     169        return -1;
     170    }
     171
     172    /**
     173     * Convert a hexadecimal string into a binary string without cache-timing
     174     * leaks
     175     *
     176     * @param string $hexString
     177     * @param bool $strictPadding
     178     * @return string (raw binary)
     179     * @throws RangeException
     180     */
     181    public static function hex2bin($hexString, $strictPadding = false)
     182    {
     183        $hex_pos = 0;
     184        $bin = '';
     185        $c_acc = 0;
     186        $hex_len = self::strlen($hexString);
     187        $state = 0;
     188        if (($hex_len & 1) !== 0) {
     189            if ($strictPadding) {
     190                throw new RangeException(
     191                    'Expected an even number of hexadecimal characters'
     192                );
     193            } else {
     194                $hexString = '0' . $hexString;
     195                ++$hex_len;
     196            }
     197        }
     198
     199        $chunk = unpack('C*', $hexString);
     200        while ($hex_pos < $hex_len) {
     201            ++$hex_pos;
     202            $c = $chunk[$hex_pos];
     203            $c_num = $c ^ 48;
     204            $c_num0 = ($c_num - 10) >> 8;
     205            $c_alpha = ($c & ~32) - 55;
     206            $c_alpha0 = (($c_alpha - 10) ^ ($c_alpha - 16)) >> 8;
     207            if (($c_num0 | $c_alpha0) === 0) {
     208                throw new RangeException(
     209                    'hexEncode() only expects hexadecimal characters'
     210                );
     211            }
     212            $c_val = ($c_num0 & $c_num) | ($c_alpha & $c_alpha0);
     213            if ($state === 0) {
     214                $c_acc = $c_val * 16;
     215            } else {
     216                $bin .= pack('C', $c_acc | $c_val);
     217            }
     218            $state ^= 1;
     219        }
     220        return $bin;
     221    }
     222
     223    /**
     224     * Cache-timing-safe variant of ord()
     225     *
     226     * @param string $chr
     227     * @return int
     228     */
     229    public static function chrToInt($chr)
     230    {
     231        $chunk = unpack('C', self::substr($chr, 0, 1));
     232        return $chunk[1];
     233    }
     234
     235    /**
     236     * Cache-timing-safe variant of ord()
     237     *
     238     * @param int $int
     239     * @return string
     240     */
     241    public static function intToChr($int)
     242    {
     243        return pack('C', $int);
     244    }
     245
     246    /**
     247     * Turn a string into an array of integers
     248     *
     249     * @param $string
     250     * @return int[]
     251     */
     252    public static function stringToIntArray($string)
     253    {
     254        return array_values(
     255            unpack('C*', $string)
     256        );
     257    }
     258
     259    /**
     260     * Turn an array of integers into a string
     261     *
     262     * @param int[] $ints
     263     * @return string
     264     */
     265    public static function intArrayToString(array $ints)
     266    {
     267        $args = $ints;
     268        foreach ($args as $i => $v) {
     269            $args[$i] = $v & 0xff;
     270        }
     271        array_unshift($args, str_repeat('C', count($ints)));
     272        return call_user_func_array('pack', $args);
     273    }
     274
     275    /**
     276     * Safe string length
     277     *
     278     * @ref mbstring.func_overload
     279     *
     280     * @param string $str
     281     * @return int
     282     */
     283    public static function strlen($str)
     284    {
     285        if (!is_string($str)) {
     286            throw new InvalidArgumentException('String expected');
     287        }
     288        if (function_exists('mb_strlen')) {
     289            return mb_strlen($str, '8bit');
     290        } else {
     291            return strlen($str);
     292        }
     293    }
     294
     295    /**
     296     * Safe substring
     297     *
     298     * @ref mbstring.func_overload
     299     *
     300     * @param string $str
     301     * @param int $start
     302     * @param int $length
     303     * @return string
     304     * @throws InvalidArgumentException
     305     */
     306    public static function substr($str, $start = 0, $length = null)
     307    {
     308        if (!is_string($str)) {
     309            throw new InvalidArgumentException('String expected');
     310        }
     311        if (PHP_VERSION_ID < 50400 && $length === null) {
     312            $length = self::strlen($str);
     313        }
     314        if (function_exists('mb_substr')) {
     315            // $length calculation above might result in a 0-length string
     316            if ($length === 0) {
     317                return '';
     318            }
     319            return mb_substr($str, $start, $length, '8bit');
     320        }
     321        if ($length === 0) {
     322            return '';
     323        }
     324        // Unlike mb_substr(), substr() doesn't accept NULL for length
     325        if ($length !== null) {
     326            return substr($str, $start, $length);
     327        } else {
     328            return substr($str, $start);
     329        }
     330    }
     331
     332    /**
     333     * Compare a 16-character byte string in constant time.
     334     *
     335     * @param string $a
     336     * @param string $b
     337     * @return bool
     338     */
     339    public static function verify_16($a, $b)
     340    {
     341        $diff = self::strlen($a) ^ self::strlen($b);
     342        for ($i = 0; $i < 16; ++$i) {
     343            $diff |= self::chrToInt($a[$i]) ^ self::chrToInt($b[$i]);
     344        }
     345        return $diff === 0;
     346    }
     347
     348    /**
     349     * Compare a 32-character byte string in constant time.
     350     *
     351     * @param string $a
     352     * @param string $b
     353     * @return bool
     354     */
     355    public static function verify_32($a, $b)
     356    {
     357        $diff = self::strlen($a) ^ self::strlen($b);
     358        for ($i = 0; $i < 32; ++$i) {
     359            $diff |= self::chrToInt($a[$i]) ^ self::chrToInt($b[$i]);
     360        }
     361        return $diff === 0;
     362    }
     363
     364    /**
     365     * Calculate $a ^ $b for two strings.
     366     *
     367     * @param string $a
     368     * @param string $b
     369     * @return string
     370     */
     371    public static function xorStrings($a, $b)
     372    {
     373        $aLen = self::strlen($a);
     374        $bLen = self::strlen($b);
     375        $d = '';
     376
     377        for ($i = 0; $i < $aLen && $i < $bLen; ++$i) {
     378            $d .= self::intToChr(self::chrToInt($a[$i]) ^ self::chrToInt($b[$i]));
     379        }
     380        return $d;
     381    }
     382}
  • wp-includes/sodium_compat/src/Core/Xsalsa20.php

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
     1<?php
     2
     3/**
     4 * Class ParagonIE_Sodium_Core_XSalsa20
     5 */
     6abstract class ParagonIE_Sodium_Core_XSalsa20 extends ParagonIE_Sodium_Core_HSalsa20
     7{
     8    /**
     9     * Expand a key and nonce into an xsalsa20 keystream.
     10     *
     11     * @param string $len
     12     * @param string $nonce
     13     * @param string $key
     14     * @return string;
     15     */
     16    public static function xsalsa20($len, $nonce, $key)
     17    {
     18        $subkey = self::hsalsa20($nonce, $key);
     19        $ret = self::salsa20($len, self::substr($nonce, 16, 8), $subkey);
     20        ParagonIE_Sodium_Compat::memzero($subkey);
     21        return $ret;
     22    }
     23
     24    /**
     25     * Encrypt a string with Xsalsa20. Doesn't provide integrity.
     26     *
     27     * @param string $message
     28     * @param string $nonce
     29     * @param string $key
     30     * @return string
     31     */
     32    public static function xsalsa20_xor($message, $nonce, $key)
     33    {
     34        return self::xorStrings(
     35            $message,
     36            self::xsalsa20(
     37                self::strlen($message),
     38                $nonce,
     39                $key
     40            )
     41        );
     42    }
     43}
  • wp-includes/sodium_compat/src/Core/Curve25519/Ge/P2.php

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
     1<?php
     2
     3/**
     4 * Class ParagonIE_Sodium_Core_Curve25519_Ge_P2
     5 */
     6class ParagonIE_Sodium_Core_Curve25519_Ge_P2
     7{
     8    /**
     9     * @var ParagonIE_Sodium_Core_Curve25519_Fe
     10     */
     11    public $X;
     12
     13    /**
     14     * @var ParagonIE_Sodium_Core_Curve25519_Fe
     15     */
     16    public $Y;
     17
     18    /**
     19     * @var ParagonIE_Sodium_Core_Curve25519_Fe
     20     */
     21    public $Z;
     22
     23    /**
     24     * ParagonIE_Sodium_Core_Curve25519_Ge_P2 constructor.
     25     * @param ParagonIE_Sodium_Core_Curve25519_Fe $x
     26     * @param ParagonIE_Sodium_Core_Curve25519_Fe $y
     27     * @param ParagonIE_Sodium_Core_Curve25519_Fe $z
     28     */
     29    public function __construct(
     30        ParagonIE_Sodium_Core_Curve25519_Fe $x = null,
     31        ParagonIE_Sodium_Core_Curve25519_Fe $y = null,
     32        ParagonIE_Sodium_Core_Curve25519_Fe $z = null
     33    ) {
     34        $this->X = $x;
     35        $this->Y = $y;
     36        $this->Z = $z;
     37    }
     38}
  • wp-includes/sodium_compat/tests/unit/Curve25519Test.php

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
     1<?php
     2
     3class Curve25519Test extends PHPUnit_Framework_TestCase
     4{
     5    public function setUp()
     6    {
     7        ParagonIE_Sodium_Compat::$disableFallbackForUnitTests = true;
     8    }
     9
     10    /**
     11     * @covers ParagonIE_Sodium_Core_Curve25519::fe_0()
     12     */
     13    public function testFe0()
     14    {
     15        $f = array(
     16            0,
     17            0,
     18            0,
     19            0,
     20            0,
     21            0,
     22            0,
     23            0,
     24            0,
     25            0
     26        );
     27        $fe_f = ParagonIE_Sodium_Core_Curve25519_Fe::fromArray($f);
     28        $r = ParagonIE_Sodium_Core_Curve25519::fe_0();
     29        for ($i = 0; $i < 10; ++$i) {
     30            $this->assertEquals($r[$i], $fe_f[$i]);
     31        }
     32    }
     33
     34    /**
     35     * @covers ParagonIE_Sodium_Core_Curve25519::fe_1()
     36     */
     37    public function testFe1()
     38    {
     39        $f = array(
     40            1,
     41            0,
     42            0,
     43            0,
     44            0,
     45            0,
     46            0,
     47            0,
     48            0,
     49            0
     50        );
     51        $fe_f = ParagonIE_Sodium_Core_Curve25519_Fe::fromArray($f);
     52        $r = ParagonIE_Sodium_Core_Curve25519::fe_1();
     53        for ($i = 0; $i < 10; ++$i) {
     54            $this->assertEquals($r[$i], $fe_f[$i]);
     55        }
     56    }
     57
     58    /**
     59     * @covers ParagonIE_Sodium_Core_Curve25519::fe_add()
     60     */
     61    public function testFeAdd()
     62    {
     63        $f = array(
     64            random_int(0, 65535),
     65            random_int(0, 65535),
     66            random_int(0, 65535),
     67            random_int(0, 65535),
     68            random_int(0, 65535),
     69            random_int(0, 65535),
     70            random_int(0, 65535),
     71            random_int(0, 65535),
     72            random_int(0, 65535),
     73            random_int(0, 65535)
     74        );
     75        $g = array(
     76            random_int(0, 65535),
     77            random_int(0, 65535),
     78            random_int(0, 65535),
     79            random_int(0, 65535),
     80            random_int(0, 65535),
     81            random_int(0, 65535),
     82            random_int(0, 65535),
     83            random_int(0, 65535),
     84            random_int(0, 65535),
     85            random_int(0, 65535)
     86        );
     87        $h = array();
     88        for ($i = 0; $i < 10; ++$i) {
     89            $h[$i] = $f[$i] + $g[$i];
     90        }
     91
     92        $fe_f = ParagonIE_Sodium_Core_Curve25519_Fe::fromArray($f);
     93        $fe_g = ParagonIE_Sodium_Core_Curve25519_Fe::fromArray($g);
     94        $fe_h = ParagonIE_Sodium_Core_Curve25519_Fe::fromArray($h);
     95        $r = ParagonIE_Sodium_Core_Curve25519::fe_add($fe_f, $fe_g);
     96
     97        for ($i = 0; $i < 10; ++$i) {
     98            $this->assertEquals($r[$i], $fe_h[$i]);
     99        }
     100        $this->assertEquals($r, $fe_h, 'Addition error!');
     101    }
     102
     103    /**
     104     * @covers ParagonIE_Sodium_Core_Curve25519::fe_sub()
     105     */
     106    public function testFeSub()
     107    {
     108        $f = array(
     109            random_int(0, 65535),
     110            random_int(0, 65535),
     111            random_int(0, 65535),
     112            random_int(0, 65535),
     113            random_int(0, 65535),
     114            random_int(0, 65535),
     115            random_int(0, 65535),
     116            random_int(0, 65535),
     117            random_int(0, 65535),
     118            random_int(0, 65535)
     119        );
     120        $g = array(
     121            random_int(0, 65535),
     122            random_int(0, 65535),
     123            random_int(0, 65535),
     124            random_int(0, 65535),
     125            random_int(0, 65535),
     126            random_int(0, 65535),
     127            random_int(0, 65535),
     128            random_int(0, 65535),
     129            random_int(0, 65535),
     130            random_int(0, 65535)
     131        );
     132        $h = array();
     133        for ($i = 0; $i < 10; ++$i) {
     134            $h[$i] = $f[$i] - $g[$i];
     135        }
     136
     137        $fe_f = ParagonIE_Sodium_Core_Curve25519_Fe::fromArray($f);
     138        $fe_g = ParagonIE_Sodium_Core_Curve25519_Fe::fromArray($g);
     139        $fe_h = ParagonIE_Sodium_Core_Curve25519_Fe::fromArray($h);
     140        $r = ParagonIE_Sodium_Core_Curve25519::fe_sub($fe_f, $fe_g);
     141
     142        for ($i = 0; $i < 10; ++$i) {
     143            $this->assertEquals($r[$i], $fe_h[$i]);
     144        }
     145        $this->assertEquals($r, $fe_h, 'Subtraction error!');
     146    }
     147
     148    /**
     149     * @covers ParagonIE_Sodium_Core_Curve25519::sc_reduce()
     150     */
     151    public function testReduce()
     152    {
     153        $input = ParagonIE_Sodium_Core_Util::hex2bin(
     154            "dc0e1b48b1f2d9d3a6638a43c986c49ecbfafba209fff7a801f9d8f776c1fc79" .
     155            "5dd9dd8f4c272b92210c923ba7940955136f7e68c4bee52a6562f8171785ce10"
     156        );
     157        $reduced = ParagonIE_Sodium_Core_Curve25519::sc_reduce($input);
     158        $this->assertSame(
     159            'd8e7f39643da186a4a690c8cf6a7987bc4d2fb7bede4e7cec89f8175da27730a',
     160            bin2hex($reduced),
     161            'sd_reduce is not working'
     162        );
     163    }
     164
     165    /**
     166     * @covers ParagonIE_Sodium_Core_Curve25519::ge_select()
     167     */
     168    public function testGeSelect()
     169    {
     170        $this->assertEquals(
     171            ParagonIE_Sodium_Core_Curve25519::ge_select(0, 6),
     172            new ParagonIE_Sodium_Core_Curve25519_Ge_Precomp(
     173                ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
     174                    array(-15371964, -12862754, 32573250, 4720197, -26436522, 5875511, -19188627, -15224819, -9818940, -12085777)
     175                ),
     176                ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
     177                    array(-8549212, 109983, 15149363, 2178705, 22900618, 4543417, 3044240, -15689887, 1762328, 14866737)
     178                ),
     179                ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
     180                    array(-18199695, -15951423, -10473290, 1707278, -17185920, 3916101, -28236412, 3959421, 27914454, 4383652)
     181                )
     182            ),
     183            'ge_select is not working.'
     184        );
     185    }
     186
     187    /**
     188     * @covers ParagonIE_Sodium_Core_Curve25519::fe_mul()
     189     */
     190    public function testFeMul()
     191    {
     192        $f = ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
     193            array(
     194                26853523,
     195                -15767542,
     196                10850706,
     197                -434120,
     198                -20393796,
     199                -13094191,
     200                -4793868,
     201                1643574,
     202                11273642,
     203                14083967
     204            )
     205        );
     206
     207        $g = ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
     208            array(
     209                -10913610,
     210                13857413,
     211                -15372611,
     212                6949391,
     213                114729,
     214                -8787816,
     215                -6275908,
     216                -3247719,
     217                -18696448,
     218                -12055116
     219            )
     220        );
     221
     222        $expected = ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
     223            array(
     224                -25012118,
     225                15881590,
     226                -29167576,
     227                -8241728,
     228                -26366797,
     229                6116011,
     230                -16287663,
     231                -1425685,
     232                -9694368,
     233                -16104023
     234            )
     235        );
     236
     237        $h = ParagonIE_Sodium_Core_Curve25519::fe_mul($f, $g);
     238        $this->assertEquals($expected, $h);
     239
     240        $this->assertEquals(
     241            $expected,
     242            ParagonIE_Sodium_Core_Curve25519::fe_mul($h, ParagonIE_Sodium_Core_Curve25519::fe_1())
     243        );
     244
     245        $this->assertEquals(
     246            $expected,
     247            ParagonIE_Sodium_Core_Curve25519::fe_mul(ParagonIE_Sodium_Core_Curve25519::fe_1(), $h)
     248        );
     249        $z = ParagonIE_Sodium_Core_Curve25519::fe_0();
     250        $this->assertEquals(
     251            $z,
     252            ParagonIE_Sodium_Core_Curve25519::fe_mul($z, $h)
     253        );
     254    }
     255
     256    /**
     257     * @covers ParagonIE_Sodium_Core_Curve25519::ge_madd()
     258     */
     259    public function testGeMAdd()
     260    {
     261        $p = new ParagonIE_Sodium_Core_Curve25519_Ge_P3(
     262            ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
     263                array(0,0,0,0,0,0,0,0,0,0)
     264            ),
     265            ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
     266                array(1,0,0,0,0,0,0,0,0,0)
     267            ),
     268            ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
     269                array(1,0,0,0,0,0,0,0,0,0)
     270            ),
     271            ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
     272                array(0,0,0,0,0,0,0,0,0,0)
     273            )
     274        );
     275
     276        $q = new ParagonIE_Sodium_Core_Curve25519_Ge_Precomp(
     277            ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
     278                array(-8549212, 109983, 15149363, 2178705, 22900618, 4543417, 3044240, -15689887, 1762328, 14866737)
     279            ),
     280            ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
     281                array(-15371964, -12862754, 32573250, 4720197, -26436522, 5875511, -19188627, -15224819, -9818940, -12085777)
     282            ),
     283            ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
     284                array(18199695, 15951423, 10473290, -1707278, 17185920, -3916101, 28236412, -3959421, -27914454, -4383652)
     285            )
     286        );
     287
     288        $expected = new ParagonIE_Sodium_Core_Curve25519_Ge_P1p1(
     289            ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
     290                array(6822752, 12972737, -17423887, -2541492, 49337140, -1332094, 22232867, -465068, 11581268, 26952514)
     291            ),
     292            ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
     293                array(-23921176, -12752771, 47722613, 6898902, -3535904, 10418928, -16144387, -30914706, -8056612, 2780960)
     294            ),
     295            ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
     296                array(2,0,0,0,0,0,0,0,0,0)
     297            ),
     298            ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
     299                array(2,0,0,0,0,0,0,0,0,0)
     300            )
     301        );
     302
     303        $r = new ParagonIE_Sodium_Core_Curve25519_Ge_P1p1();
     304        $this->assertEquals(
     305            $expected,
     306            ParagonIE_Sodium_Core_Curve25519::ge_madd($r, $p, $q),
     307            'ge_madd is still broken'
     308        );
     309
     310        // $this->assertSame(true, true); return;
     311        $h = new ParagonIE_Sodium_Core_Curve25519_Ge_P3(
     312            ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
     313                array(0,0,0,0,0,0,0,0,0,0)
     314            ),
     315            ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
     316                array(1,0,0,0,0,0,0,0,0,0)
     317            ),
     318            ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
     319                array(1,0,0,0,0,0,0,0,0,0)
     320            ),
     321            ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
     322                array(0,0,0,0,0,0,0,0,0,0)
     323            )
     324        );
     325
     326        $t = new ParagonIE_Sodium_Core_Curve25519_Ge_Precomp(
     327            ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
     328                array(23599295, -8306047, -11193664, -7687416, 13236774, 10506355, 7464579, 9656445, 13059162, 103743971)
     329            ),
     330            ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
     331                array(-17036878, 13921892, 10945806, -6033431, 27105052, -16084379, -28926210, 15006023, 3284568, -6276540)
     332            ),
     333            ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
     334                array(-7798556, -16710257, -3033922, -2874086, -28997861, -2835604, -32406664, 3839045, 641708, 101325)
     335            )
     336        );
     337
     338        $expected = new ParagonIE_Sodium_Core_Curve25519_Ge_P1p1(
     339            ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
     340                array(40636230, -22227939, -22139470, -1653985, -13868278, 26590734, 36390789, -5349578, 9774594, 9357215)
     341            ),
     342            ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
     343                array(6562474, 5615845, -247858, -13720847, 40341826, -5578024, -21461631, 24662468, 16343730, -3195865)
     344            ),
     345            ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
     346                array(2,0,0,0,0,0,0,0,0,0)
     347            ),
     348            ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
     349                array(2,0,0,0,0,0,0,0,0,0)
     350            )
     351        );
     352
     353        $r = new ParagonIE_Sodium_Core_Curve25519_Ge_P1p1();
     354        $this->assertEquals(
     355            $expected,
     356            ParagonIE_Sodium_Core_Curve25519::ge_madd($r, $h, $t),
     357            'ge_madd is not working'
     358        );
     359
     360        $h = new ParagonIE_Sodium_Core_Curve25519_Ge_P3(
     361            ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
     362                array(0,0,0,0,0,0,0,0,0,0)
     363            ),
     364            ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
     365                array(1,0,0,0,0,0,0,0,0,0)
     366            ),
     367            ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
     368                array(1,0,0,0,0,0,0,0,0,0)
     369            ),
     370            ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
     371                array(0,0,0,0,0,0,0,0,0,0)
     372            )
     373        );
     374
     375        $t = new ParagonIE_Sodium_Core_Curve25519_Ge_Precomp(
     376            ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
     377                array(-12815894, -12976347, -21581243, 11784320, -25355658, -2750717, -11717903, -3814571, -358445, -10211303)
     378            ),
     379            ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
     380                array(-21703237, 6903825, 27185491, 6451973, -29577724, -9554005, -15616551, 11189268, -26829678, -53190817)
     381            ),
     382            ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
     383                array(26966642, 11152617, 32442495, 15396054, 14353839, -12752335, -3128826, -9541118, -15472047, -4166697)
     384            )
     385        );
     386
     387        $expected = new ParagonIE_Sodium_Core_Curve25519_Ge_P1p1(
     388            ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
     389                array(8887381, -19880172, -48766734, 5332347, 4222066, 6803288, 3898648, -15003839, 26471233, -24129350)
     390            ),
     391            ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
     392                array(-34519169, -6072522, 5604248, 18236293, -54933382, -12304722, -27334454, 7374697, -27188123, 3706744)
     393            ),
     394            ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
     395                array(2,0,0,0,0,0,0,0,0,0)
     396            ),
     397            ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
     398                array(2,0,0,0,0,0,0,0,0,0)
     399            )
     400        );
     401        $r = new ParagonIE_Sodium_Core_Curve25519_Ge_P1p1();
     402        $this->assertEquals(
     403            $expected,
     404            ParagonIE_Sodium_Core_Curve25519::ge_madd($r, $h, $t),
     405            'ge_madd is not working'
     406        );
     407    }
     408
     409   
     410    public function testGeScalarmultBase()
     411    {
     412        $nonce = ParagonIE_Sodium_Core_Util::hex2bin(
     413            'a5cdb7382d5282472312e739b7b8fded4b0bc73a8d3b7ac24e6ee259df74800a' .
     414            'c19b35ef3130ed0474e0f0cc4d9ee277788775036b7025aed15c3beb29ff4eab'
     415        );
     416        $R = ParagonIE_Sodium_Core_Curve25519::ge_scalarmult_base($nonce);
     417        $expected = new ParagonIE_Sodium_Core_Curve25519_Ge_P3(
     418            ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(array(
     419                -23932472,
     420                11221871,
     421                27518927,
     422                -12970994,
     423                14275856,
     424                4619861,
     425                -14347453,
     426                6713345,
     427                -33117680,
     428                -10663750
     429            )),
     430            ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(array(
     431                14689788,
     432                -10448958,
     433                -30321432,
     434                -9014186,
     435                14446585,
     436                -7985136,
     437                27805771,
     438                -13751241,
     439                -1536736,
     440                -13958946
     441            )),
     442            ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(array(
     443                19689758,
     444                -6173146,
     445                -15886452,
     446                5649798,
     447                -24861313,
     448                -12384199,
     449                -2662028,
     450                16072970,
     451                5918454,
     452                14582476
     453            )),
     454            ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(array(
     455                -9719484,
     456                -15496290,
     457                -31004425,
     458                -7546822,
     459                12427063,
     460                11453174,
     461                -8594732,
     462                -14149517,
     463                27692259,
     464                -14101917
     465            ))
     466        );
     467        $this->assertEquals(
     468            $expected,
     469            $R,
     470            'Check ge_scalarmult_base for correctness'
     471        );
     472
     473        $bytes = ParagonIE_Sodium_Core_Curve25519::ge_p3_tobytes($R);
     474        $this->assertSame(
     475            '36a6d2748f6ab8f76c122a562d55343cb7c6f15c8a45bd55bd8b9e9fadd2363f',
     476            bin2hex($bytes),
     477            'Check ge_p3_tobytes for correctness'
     478        );
     479    }
     480
     481    /**
     482     * @covers ParagonIE_Sodium_Core_Curve25519::ge_double_scalarmult_vartime()
     483     */
     484    public function testGeDoubleScalarMultVartime()
     485    {
     486        $h = ParagonIE_Sodium_Core_Util::hex2bin(
     487            'fc2ef90e2ddab38c55d0edbf41167048061a03b99d00112dcc92777c1b17300c' .
     488            'bd84d56b93d272eb01a2ffb5557bda3922360e402c29d05cda3f0debabaf5ce5'
     489        );
     490        $A = new ParagonIE_Sodium_Core_Curve25519_Ge_P3(
     491            ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(array(
     492                25569346,
     493                24607350,
     494                21422669,
     495                3164952,
     496                51116803,
     497                27944728,
     498                23859688,
     499                12129629,
     500                33577468,
     501                23235570
     502            )),
     503            ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(array(
     504                16253166, 2599808, 30616947, -12747262, 372730, 8894334, 9139202, -197177, -24298945, 15942855
     505            )),
     506            ParagonIE_Sodium_Core_Curve25519::fe_1(),
     507            ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(array(
     508                -28155508, 13944970, 2511703, 16462880, 15250894, -7952383, -19629302, 16022930, 1783986, 16320964
     509            ))
     510        );
     511        $sig = ParagonIE_Sodium_Core_Util::hex2bin(
     512            '36a6d2748f6ab8f76c122a562d55343cb7c6f15c8a45bd55bd8b9e9fadd2363f' .
     513            '370cb78fba42c550d487b9bd7413312b6490c8b3ee2cea638997172a9c8c250f'
     514        );
     515        $expected = new ParagonIE_Sodium_Core_Curve25519_Ge_P2(
     516            ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(array(
     517                -18667682,
     518                9847093,
     519                7256576,
     520                -7033042,
     521                32767777,
     522                -10224836,
     523                25608854,
     524                6989354,
     525                -19138147,
     526                -13642525
     527            )),
     528            ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(array(
     529                6317192,
     530                4477233,
     531                24373531,
     532                14977415,
     533                -10754696,
     534                -12573560,
     535                -20847592,
     536                8319048,
     537                13730645,
     538                -7760907
     539            )),
     540            ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(array(
     541                32680048,
     542                -15342934,
     543                3837898,
     544                8050201,
     545                15422085,
     546                14178962,
     547                -6403825,
     548                -627297,
     549                24243949,
     550                12818173
     551            ))
     552        );
     553
     554        $this->assertEquals(
     555            $expected,
     556            ParagonIE_Sodium_Core_Curve25519::ge_double_scalarmult_vartime($h, $A, $sig),
     557            'ge_double_scalarmult_vartime()'
     558        );
     559    }
     560}
  • wp-includes/sodium_compat/tests/compat/SodiumCompatTest.php

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
     1<?php
     2
     3/**
     4 * Class SodiumCompatTest
     5 */
     6class SodiumCompatTest extends PHPUnit_Framework_TestCase
     7{
     8    public function setUp()
     9    {
     10        if (!extension_loaded('libsodium')) {
     11            $this->markTestSkipped('Libsodium is not installed; skipping the compatibility test suite.');
     12        }
     13        ParagonIE_Sodium_Compat::$disableFallbackForUnitTests = true;
     14    }
     15
     16    /**
     17     * @covers ParagonIE_Sodium_Core_Util::compare()
     18     */
     19    public function testCompare()
     20    {
     21        $a = pack('H*', '589a84d7ec2db8f982841cedca674ec1');
     22        $b = $a;
     23        $b[15] = 'a';
     24        $this->assertSame(
     25            \Sodium\compare($a, $b),
     26            ParagonIE_Sodium_Core_Util::compare($a, $b),
     27            bin2hex($a) . ' vs ' . bin2hex($b)
     28        );
     29
     30        $a = random_bytes(16);
     31        $b = $a;
     32        $b[15] = 'a';
     33
     34        $this->assertSame(
     35            \Sodium\compare($a, $b),
     36            ParagonIE_Sodium_Core_Util::compare($a, $b),
     37            bin2hex($a)
     38        );
     39    }
     40
     41    /**
     42     * @covers ParagonIE_Sodium_Core_Util::bin2hex()
     43     */
     44    public function testBin2hex()
     45    {
     46        $str = random_bytes(random_int(1, 63));
     47        $this->assertSame(
     48            \Sodium\bin2hex($str),
     49            ParagonIE_Sodium_Core_Util::bin2hex($str)
     50        );
     51    }
     52
     53    /**
     54     * @covers ParagonIE_Sodium_Core_Util::hex2bin()
     55     */
     56    public function testHex2bin()
     57    {
     58        $str = bin2hex(random_bytes(random_int(1, 63)));
     59        $this->assertSame(
     60            \Sodium\hex2bin($str),
     61            ParagonIE_Sodium_Core_Util::hex2bin($str)
     62        );
     63    }
     64
     65    /**
     66     *
     67     */
     68    public function testCryptoAuth()
     69    {
     70        $message = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
     71        $key = random_bytes(32);
     72
     73        $this->assertSame(
     74            bin2hex(\Sodium\crypto_auth($message, $key)),
     75            bin2hex(ParagonIE_Sodium_Compat::crypto_auth($message, $key))
     76        );
     77        $mac = \Sodium\crypto_auth($message, $key);
     78        $this->assertTrue(
     79            ParagonIE_Sodium_Compat::crypto_auth_verify($mac, $message, $key)
     80        );
     81    }
     82
     83    /**
     84     * @covers ParagonIE_Sodium_Compat::crypto_box()
     85     * @covers ParagonIE_Sodium_Compat::crypto_box_open()
     86     */
     87    public function testCryptoBox()
     88    {
     89        $nonce = str_repeat("\x00", 24);
     90        $message = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
     91
     92        $alice_box_kp = \Sodium\crypto_box_keypair();
     93        $alice_box_secretkey = \Sodium\crypto_box_secretkey($alice_box_kp);
     94        $alice_box_publickey = \Sodium\crypto_box_publickey($alice_box_kp);
     95
     96        $bob_box_kp = \Sodium\crypto_box_keypair();
     97        $bob_box_secretkey = \Sodium\crypto_box_secretkey($bob_box_kp);
     98        $bob_box_publickey = \Sodium\crypto_box_publickey($bob_box_kp);
     99
     100        $alice_to_bob = \Sodium\crypto_box_keypair_from_secretkey_and_publickey(
     101            $alice_box_secretkey,
     102            $bob_box_publickey
     103        );
     104        $bob_to_alice = \Sodium\crypto_box_keypair_from_secretkey_and_publickey(
     105            $bob_box_secretkey,
     106            $alice_box_publickey
     107        );
     108        $bob_to_alice2 = ParagonIE_Sodium_Crypto::box_keypair_from_secretkey_and_publickey(
     109            $bob_box_secretkey,
     110            $alice_box_publickey
     111        );
     112        $this->assertSame($bob_to_alice, $bob_to_alice2);
     113
     114        $this->assertSame(
     115            bin2hex(\Sodium\crypto_box($message, $nonce, $alice_to_bob)),
     116            bin2hex(ParagonIE_Sodium_Compat::crypto_box($message, $nonce, $alice_to_bob)),
     117            'box'
     118        );
     119        $this->assertSame(
     120            $message,
     121            ParagonIE_Sodium_Compat::crypto_box_open(
     122                \Sodium\crypto_box($message, $nonce, $alice_to_bob),
     123                $nonce,
     124                $bob_to_alice
     125            )
     126        );
     127
     128        $message = str_repeat("Lorem ipsum dolor sit amet, consectetur adipiscing elit. ", 8);
     129        $this->assertSame(
     130            bin2hex(\Sodium\crypto_box($message, $nonce, $alice_to_bob)),
     131            bin2hex(ParagonIE_Sodium_Compat::crypto_box($message, $nonce, $alice_to_bob)),
     132            'crypto_box is failing with large messages'
     133        );
     134        $this->assertSame(
     135            bin2hex($message),
     136            bin2hex(
     137                ParagonIE_Sodium_Compat::crypto_box_open(
     138                    \Sodium\crypto_box($message, $nonce, $alice_to_bob),
     139                    $nonce,
     140                    $bob_to_alice
     141                )
     142            )
     143        );
     144    }
     145
     146    public function testCryptoBoxSeal()
     147    {
     148        $msg = ParagonIE_Sodium_Core_Util::hex2bin(
     149            '7375f4094f1151640bd853cb13dbc1a0ee9e13b0287a89d34fa2f6732be9de13f88457553d'.
     150            '768347116522d6d32c9cb353ef07aa7c83bd129b2bb5db35b28334c935b24f2639405a0604'
     151        );
     152        $kp = ParagonIE_Sodium_Core_Util::hex2bin(
     153            '36a6c2b96a650d80bf7e025e0f58f3d636339575defb370801a54213bd54582d'.
     154            '5aecbcf7866e7a4d58a6c1317e2b955f54ecbe2fcbbf7d262c10636ed524480c'
     155        );
     156        $alice_opened2 = ParagonIE_Sodium_Compat::crypto_box_seal_open($msg, $kp);
     157        $this->assertSame(
     158            bin2hex('This is for your eyes only'),
     159            bin2hex($alice_opened2),
     160            'Decryption failed #2'
     161        );
     162        $alice_box_kp = ParagonIE_Sodium_Core_Util::hex2bin(
     163            '15b36cb00213373fb3fb03958fb0cc0012ecaca112fd249d3cf0961e311caac9' .
     164            'fb4cb34f74a928b79123333c1e63d991060244cda98affee14c3398c6d315574'
     165        );
     166        $alice_box_publickey = ParagonIE_Sodium_Core_Util::hex2bin(
     167            'fb4cb34f74a928b79123333c1e63d991060244cda98affee14c3398c6d315574'
     168        );
     169        $anonymous_message_to_alice = \Sodium\crypto_box_seal(
     170            'Anonymous message',
     171            $alice_box_publickey);
     172        $decrypted_message = ParagonIE_Sodium_Compat::crypto_box_seal_open(
     173            $anonymous_message_to_alice,
     174            $alice_box_kp
     175        );
     176        $this->assertSame(
     177            'Anonymous message',
     178            $decrypted_message
     179        );
     180
     181        $messages = array(
     182            'test',
     183            'slightly longer message',
     184            str_repeat('a', 29) . ' 32',
     185            str_repeat('a', 30) . ' 33',
     186            str_repeat('a', 31) . ' 34',
     187            "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
     188        );
     189        foreach ($messages as $message) {
     190            $sealed_to_alice1 = \Sodium\crypto_box_seal($message, $alice_box_publickey);
     191            $sealed_to_alice2 = ParagonIE_Sodium_Compat::crypto_box_seal(
     192                $message,
     193                $alice_box_publickey
     194            );
     195
     196            $this->assertSame(
     197                strlen($sealed_to_alice1),
     198                strlen($sealed_to_alice2),
     199                'String length should not differ'
     200            );
     201
     202            $alice_opened1 = ParagonIE_Sodium_Compat::crypto_box_seal_open($sealed_to_alice1, $alice_box_kp);
     203            $this->assertSame(
     204                bin2hex(\Sodium\crypto_box_seal_open($sealed_to_alice1, $alice_box_kp)),
     205                bin2hex($message),
     206                'Decryption failed #1: ' . $message
     207            );
     208            $this->assertSame(
     209                bin2hex($message),
     210                bin2hex($alice_opened1),
     211                'Decryption failed #1: ' . $message
     212            );
     213            $this->assertSame(
     214                bin2hex($alice_opened1),
     215                bin2hex(\Sodium\crypto_box_seal_open($sealed_to_alice1, $alice_box_kp)),
     216                'Decryption failed #1: ' . $message
     217            );
     218
     219            $alice_opened2 = ParagonIE_Sodium_Compat::crypto_box_seal_open(
     220                $sealed_to_alice2,
     221                $alice_box_kp
     222            );
     223
     224            $this->assertSame(
     225                $message,
     226                $alice_opened2,
     227                'Decryption failed #2: ' . $message
     228            );
     229            $this->assertSame(
     230                bin2hex(\Sodium\crypto_box_seal_open($sealed_to_alice2, $alice_box_kp)),
     231                bin2hex($message),
     232                'Decryption failed #2: ' . $message
     233            );
     234            $this->assertSame(
     235                bin2hex(\Sodium\crypto_box_seal_open($sealed_to_alice2, $alice_box_kp)),
     236                bin2hex($alice_opened2),
     237                'Decryption failed #2: ' . $message
     238            );
     239        }
     240    }
     241
     242    /**
     243     * @covers ParagonIE_Sodium_Crypto::generichash()
     244     */
     245    public function testCryptoGenerichash()
     246    {
     247        $this->assertSame(
     248            bin2hex(\Sodium\crypto_generichash('apple')),
     249            bin2hex(ParagonIE_Sodium_Compat::crypto_generichash('apple')),
     250            'BLAKE2b implementation'
     251        );
     252
     253        $this->assertSame(
     254            bin2hex(\Sodium\crypto_generichash('apple', 'catastrophic failure')),
     255            bin2hex(ParagonIE_Sodium_Compat::crypto_generichash('apple', 'catastrophic failure')),
     256            'BLAKE2b with a key'
     257        );
     258
     259        $this->assertSame(
     260            bin2hex(\Sodium\crypto_generichash('apple', '', 64)),
     261            bin2hex(ParagonIE_Sodium_Compat::crypto_generichash('apple', '', 64)),
     262            'BLAKE2b implementation with output length'
     263        );
     264
     265        $this->assertSame(
     266            bin2hex(\Sodium\crypto_generichash('apple', 'catastrophic failure', 24)),
     267            bin2hex(ParagonIE_Sodium_Compat::crypto_generichash('apple', 'catastrophic failure', 24)),
     268            'BLAKE2b implementation with output length'
     269        );
     270    }
     271
     272    /**
     273     * @covers ParagonIE_Sodium_Crypto::generichash_init()
     274     * @covers ParagonIE_Sodium_Crypto::generichash_update()
     275     * @covers ParagonIE_Sodium_Crypto::generichash_final()
     276     */
     277    public function testCryptoGenerichashStream()
     278    {
     279        $key =  "\x1c" . str_repeat("\x80", 30) . "\xaf";
     280        $ctx = \Sodium\crypto_generichash_init($key);
     281        $this->assertSame(
     282            bin2hex($ctx),
     283            bin2hex(ParagonIE_Sodium_Compat::crypto_generichash_init($key)),
     284            'BLAKE2b Context Serialization'
     285        );
     286
     287        $subCtx = ParagonIE_Sodium_Core_BLAKE2b::stringToContext($ctx);
     288        $this->assertSame(
     289            bin2hex($ctx),
     290            bin2hex(ParagonIE_Sodium_Core_BLAKE2b::contextToString($subCtx)),
     291            'Context serialization / deserialization'
     292        );
     293        $this->assertEquals(
     294            $subCtx,
     295            ParagonIE_Sodium_Core_BLAKE2b::stringToContext(
     296                ParagonIE_Sodium_Core_BLAKE2b::contextToString($subCtx)
     297            ),
     298            'Determinism'
     299        );
     300
     301        $nativeCtx = '';
     302        for ($i = 0; $i < ParagonIE_Sodium_Core_Util::strlen($ctx); ++$i) {
     303            $nativeCtx .= $ctx[$i];
     304        }
     305
     306        \Sodium\crypto_generichash_update($nativeCtx, 'Paragon Initiative');
     307        ParagonIE_Sodium_Compat::crypto_generichash_update($ctx, 'Paragon Initiative');
     308
     309        $this->assertSame(
     310            bin2hex($nativeCtx),
     311            bin2hex($ctx),
     312            'generichash_update() 1'
     313        );
     314        \Sodium\crypto_generichash_update($nativeCtx, ' Enterprises, LLC');
     315        ParagonIE_Sodium_Compat::crypto_generichash_update($ctx, ' Enterprises, LLC');
     316
     317        $this->assertSame(
     318            bin2hex($nativeCtx),
     319            bin2hex($ctx),
     320            'generichash_update() 2'
     321        );
     322
     323        $this->assertSame(
     324            bin2hex(\Sodium\crypto_generichash_final($nativeCtx, 32)),
     325            bin2hex(ParagonIE_Sodium_Compat::crypto_generichash_final($ctx, 32)),
     326            'generichash_final()'
     327        );
     328    }
     329
     330    public function testSignKeypair()
     331    {
     332        $seed = random_bytes(32);
     333        $kp = \Sodium\crypto_sign_seed_keypair($seed);
     334        $this->assertSame(
     335            bin2hex($kp),
     336            bin2hex(
     337                ParagonIE_Sodium_Compat::crypto_sign_seed_keypair($seed)
     338            ),
     339            'crypto_sign_seed_keypair() is invalid.'
     340        );
     341        $secret = \Sodium\crypto_sign_secretkey($kp);
     342        $public = \Sodium\crypto_sign_publickey($kp);
     343
     344        $pk = '';
     345        $sk = '';
     346        ParagonIE_Sodium_Core_Ed25519::seed_keypair($pk, $sk, $seed);
     347        $this->assertSame(
     348            bin2hex($secret),
     349            bin2hex($sk),
     350            'Seed secret key'
     351        );
     352        $this->assertSame(
     353            bin2hex($public),
     354            bin2hex($pk),
     355            'Seed public key'
     356        );
     357        $keypair = ParagonIE_Sodium_Compat::crypto_sign_keypair();
     358        $secret = \Sodium\crypto_sign_secretkey($keypair);
     359        $public = \Sodium\crypto_sign_publickey($keypair);
     360
     361        $this->assertSame(
     362            bin2hex($public),
     363            bin2hex(
     364                \Sodium\crypto_sign_publickey_from_secretkey($secret)
     365            ),
     366            'Conversion from existing secret key is failing. This is a very bad thing!'
     367        );
     368
     369    }
     370
     371    public function testSignKeypair2()
     372    {
     373        $keypair = \Sodium\crypto_sign_keypair();
     374        $secret = \Sodium\crypto_sign_secretkey($keypair);
     375        $public = \Sodium\crypto_sign_publickey($keypair);
     376
     377        $this->assertSame(
     378            bin2hex($public),
     379            bin2hex(
     380                ParagonIE_Sodium_Compat::crypto_sign_publickey_from_secretkey($secret)
     381            ),
     382            'Conversion from existing secret key is failing. This is a very bad thing!'
     383        );
     384    }
     385
     386    /**
     387     * @covers ParagonIE_Sodium_Compat::crypto_sign()
     388     * @covers ParagonIE_Sodium_Compat::crypto_sign_open()
     389     * @covers ParagonIE_Sodium_Compat::crypto_sign_detached()
     390     * @covers ParagonIE_Sodium_Compat::crypto_sign_verify_detached()
     391     */
     392    public function testCryptoSign()
     393    {
     394        $keypair = ParagonIE_Sodium_Core_Util::hex2bin(
     395            'fcdf31aae72e280cc760186d83e41be216fe1f2c7407dd393ad3a45a2fa501a4' .
     396            'ee00f800ae9e986b994ec0af67fe6b017eb78704e81639eee7efa3d3a831d1bc' .
     397            'ee00f800ae9e986b994ec0af67fe6b017eb78704e81639eee7efa3d3a831d1bc'
     398        );
     399        $secret = \Sodium\crypto_sign_secretkey($keypair);
     400        $public = \Sodium\crypto_sign_publickey($keypair);
     401
     402        $this->assertSame(
     403            $secret,
     404            ParagonIE_Sodium_Compat::crypto_sign_secretkey($keypair),
     405            'crypto_sign_secretkey() is broken'
     406        );
     407        $this->assertSame(
     408            $public,
     409            ParagonIE_Sodium_Compat::crypto_sign_publickey($keypair),
     410            'crypto_sign_publickey() is broken'
     411        );
     412
     413        $message = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
     414        $expected =
     415        '36a6d2748f6ab8f76c122a562d55343cb7c6f15c8a45bd55bd8b9e9fadd2363f' .
     416        '370cb78fba42c550d487b9bd7413312b6490c8b3ee2cea638997172a9c8c250f';
     417
     418        $this->assertSame(
     419            $expected,
     420            bin2hex(\Sodium\crypto_sign_detached($message, $secret)),
     421            'Generated different signatures'
     422        );
     423
     424        $this->assertSame(
     425            bin2hex(\Sodium\crypto_sign_detached($message, $secret)),
     426            bin2hex(ParagonIE_Sodium_Crypto::sign_detached($message, $secret)),
     427            'Generated different signatures'
     428        ); 
     429
     430        $this->assertSame(
     431            $expected,
     432            bin2hex(ParagonIE_Sodium_Crypto::sign_detached($message, $secret)),
     433            'Generated different signatures'
     434        );
     435
     436        $message = 'Test message: ' . base64_encode(random_bytes(33));
     437        $keypair = \Sodium\crypto_sign_keypair();
     438        $secret = \Sodium\crypto_sign_secretkey($keypair);
     439        $public = \Sodium\crypto_sign_publickey($keypair);
     440        $public2 = ParagonIE_Sodium_Compat::crypto_sign_publickey($keypair);
     441        $this->assertSame($public, $public2);
     442
     443        $signature = \Sodium\crypto_sign_detached($message, $secret);
     444        $this->assertSame(
     445            bin2hex($signature),
     446            bin2hex(ParagonIE_Sodium_Crypto::sign_detached($message, $secret)),
     447            'Generated different signatures'
     448        );
     449        $this->assertTrue(
     450            ParagonIE_Sodium_Crypto::sign_verify_detached($signature, $message, $public),
     451            'Signature verification failed in compatibility test.'
     452        );
     453
     454        // Signed messages (NaCl compatibility):
     455        $signed = \Sodium\crypto_sign($message, $secret);
     456        $this->assertSame(
     457            bin2hex($signed),
     458            bin2hex(ParagonIE_Sodium_Crypto::sign($message, $secret)),
     459            'Basic crypto_sign works'
     460        );
     461
     462        $this->assertSame(
     463            bin2hex(\Sodium\crypto_sign_open($signed, $public)),
     464            bin2hex(ParagonIE_Sodium_Crypto::sign_open($signed, $public)),
     465            'Basic crypto_sign_open works'
     466        );
     467    }
     468
     469    /**
     470     * @covers ParagonIE_Sodium_Compat::crypto_secretbox()
     471     */
     472    public function testCryptoSecretBox()
     473    {
     474        $key = str_repeat("\x80", 32);
     475        $nonce = str_repeat("\x00", 24);
     476        $message = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
     477
     478        $this->assertSame(
     479            substr(
     480                bin2hex(\Sodium\crypto_secretbox($message, $nonce, $key)),
     481                0, 32
     482            ),
     483            substr(
     484                bin2hex(ParagonIE_Sodium_Crypto::secretbox($message, $nonce, $key)),
     485                0, 32
     486            ),
     487            'secretbox - short messages'
     488        );
     489        $this->assertSame(
     490            $message,
     491            ParagonIE_Sodium_Crypto::secretbox_open(
     492                \Sodium\crypto_secretbox($message, $nonce, $key),
     493                $nonce,
     494                $key
     495            )
     496        );
     497        $this->assertSame(
     498            $message,
     499            \Sodium\crypto_secretbox_open(
     500                ParagonIE_Sodium_Crypto::secretbox($message, $nonce, $key),
     501                $nonce,
     502                $key
     503            )
     504        );
     505        $message = str_repeat('a', 97);
     506        $this->assertSame(
     507            bin2hex(\Sodium\crypto_secretbox($message, $nonce, $key)),
     508            bin2hex(ParagonIE_Sodium_Crypto::secretbox($message, $nonce, $key)),
     509            'secretbox - long messages (multiple of 16)'
     510        );
     511
     512        $message = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
     513
     514        $message = str_repeat($message, 16);
     515
     516        $this->assertSame(
     517            bin2hex(\Sodium\crypto_secretbox($message, $nonce, $key)),
     518            bin2hex(ParagonIE_Sodium_Crypto::secretbox($message, $nonce, $key)),
     519            'secretbox - long messages (multiple of 16)'
     520        );
     521
     522        $message .= 'a';
     523
     524        $this->assertSame(
     525            bin2hex(\Sodium\crypto_secretbox($message, $nonce, $key)),
     526            bin2hex(ParagonIE_Sodium_Crypto::secretbox($message, $nonce, $key)),
     527            'secretbox - long messages (NOT a multiple of 16)'
     528        );
     529
     530        $message = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
     531
     532        $this->assertSame(
     533            bin2hex(\Sodium\crypto_secretbox($message, $nonce, $key)),
     534            bin2hex(ParagonIE_Sodium_Crypto::secretbox($message, $nonce, $key)),
     535            'secretbox - medium messages'
     536        );
     537    }
     538
     539    /**
     540     * @covers ParagonIE_Sodium_Compat::crypto_scalarmult_base()
     541     */
     542    public function testCryptoScalarmultBase()
     543    {
     544        $keypair = \Sodium\crypto_box_keypair();
     545        $secret = \Sodium\crypto_box_secretkey($keypair);
     546        $public = \Sodium\crypto_box_publickey($keypair);
     547
     548        $this->assertSame(
     549            $public,
     550            ParagonIE_Sodium_Compat::crypto_scalarmult_base($secret)
     551        );
     552    }
     553    /**
     554     * @covers ParagonIE_Sodium_Compat::crypto_scalarmult()
     555     */
     556    public function testCryptoScalarmult()
     557    {
     558        $alice_box_kp = \Sodium\crypto_box_keypair();
     559        $alice_box_secretkey = \Sodium\crypto_box_secretkey($alice_box_kp);
     560        $alice_box_publickey = \Sodium\crypto_box_publickey($alice_box_kp);
     561
     562        $bob_box_kp = \Sodium\crypto_box_keypair();
     563        $bob_box_secretkey = \Sodium\crypto_box_secretkey($bob_box_kp);
     564        $bob_box_publickey = \Sodium\crypto_box_publickey($bob_box_kp);
     565
     566        $this->assertSame(
     567            \Sodium\crypto_scalarmult($alice_box_secretkey, $bob_box_publickey),
     568            ParagonIE_Sodium_Compat::crypto_scalarmult($alice_box_secretkey, $bob_box_publickey)
     569        );
     570
     571        $this->assertSame(
     572            \Sodium\crypto_scalarmult($bob_box_secretkey, $alice_box_publickey),
     573            ParagonIE_Sodium_Compat::crypto_scalarmult($bob_box_secretkey, $alice_box_publickey)
     574        );
     575    }
     576
     577    /**
     578     * @covers ParagonIE_Sodium_Compat::crypto_box_secretkey()
     579     * @covers ParagonIE_Sodium_Compat::crypto_box_publickey()
     580     */
     581    public function testCryptoBoxKeypairs()
     582    {
     583        $keypair = \Sodium\crypto_box_keypair();
     584        $secret = \Sodium\crypto_box_secretkey($keypair);
     585        $public = \Sodium\crypto_box_publickey($keypair);
     586
     587        $this->assertSame(
     588            $secret,
     589            ParagonIE_Sodium_Compat::crypto_box_secretkey($keypair)
     590        );
     591        $this->assertSame(
     592            $public,
     593            ParagonIE_Sodium_Compat::crypto_box_publickey($keypair)
     594        );
     595    }
     596
     597    /**
     598     * @covers ParagonIE_Sodium_Compat::crypto_stream()
     599     */
     600    public function testCryptoStream()
     601    {
     602        $key = str_repeat("\x80", 32);
     603        $nonce = str_repeat("\x00", 24);
     604
     605        $streamed = \Sodium\crypto_stream(64, $nonce, $key);
     606        $this->assertSame(
     607            bin2hex($streamed),
     608            bin2hex(ParagonIE_Sodium_Compat::crypto_stream(64, $nonce, $key)),
     609            'crypto_stream_xor() is not working'
     610        );
     611        $key = random_bytes(32);
     612        $nonce = random_bytes(24);
     613
     614        $streamed = \Sodium\crypto_stream(1024, $nonce, $key);
     615        $this->assertSame(
     616            bin2hex($streamed),
     617            bin2hex(ParagonIE_Sodium_Compat::crypto_stream(1024, $nonce, $key)),
     618            'crypto_stream() is not working'
     619        );
     620    }
     621
     622    /**
     623     * @covers ParagonIE_Sodium_Compat::crypto_stream_xor()
     624     */
     625    public function testCryptoStreamXor()
     626    {
     627        $key = str_repeat("\x80", 32);
     628        $nonce = str_repeat("\x00", 24);
     629        $message = 'Test message';
     630
     631        $streamed = \Sodium\crypto_stream_xor($message, $nonce, $key);
     632        $this->assertSame(
     633            bin2hex($streamed),
     634            bin2hex(ParagonIE_Sodium_Compat::crypto_stream_xor($message, $nonce, $key)),
     635            'crypto_stream_xor() is not working'
     636        );
     637
     638        $key = random_bytes(32);
     639        $nonce = random_bytes(24);
     640
     641        $message = 'Test message: ' . base64_encode(random_bytes(93));
     642
     643        $streamed = \Sodium\crypto_stream_xor($message, $nonce, $key);
     644        $this->assertSame(
     645            bin2hex($streamed),
     646            bin2hex(ParagonIE_Sodium_Compat::crypto_stream_xor($message, $nonce, $key)),
     647            'crypto_stream_xor() is not working'
     648        );
     649    }
     650
     651    /**
     652     * @covers ParagonIE_Sodium_Compat::crypto_kx()
     653     */
     654    public function testCryptoKx()
     655    {
     656        $alice_box_kp = \Sodium\crypto_box_keypair();
     657        $alice_box_secretkey = \Sodium\crypto_box_secretkey($alice_box_kp);
     658        $alice_box_publickey = \Sodium\crypto_box_publickey($alice_box_kp);
     659
     660        $bob_box_kp = \Sodium\crypto_box_keypair();
     661        $bob_box_publickey = \Sodium\crypto_box_publickey($bob_box_kp);
     662
     663        // Let's designate Bob as the server.
     664
     665        $this->assertSame(
     666            bin2hex(
     667                \Sodium\crypto_kx(
     668                    $alice_box_secretkey, $bob_box_publickey,
     669                    $alice_box_publickey, $bob_box_publickey
     670                )
     671            ),
     672            bin2hex(
     673                ParagonIE_Sodium_Compat::crypto_kx(
     674                    $alice_box_secretkey, $bob_box_publickey,
     675                    $alice_box_publickey, $bob_box_publickey
     676                )
     677            )
     678        );
     679    }
     680
     681    /**
     682     *
     683     */
     684    public function testCryptoShorthash()
     685    {
     686        $message = str_repeat("\x00", 8);
     687        $key = str_repeat("\x00", 16);
     688        $this->shorthashVerify($message, $key);
     689
     690        $key = str_repeat("\xff", 16);
     691        $this->shorthashVerify($message, $key);
     692
     693        $message = str_repeat("\x01", 8);
     694        $this->shorthashVerify($message, $key);
     695
     696        $message = str_repeat("\x01", 7) . "\x02";
     697        $this->shorthashVerify($message, $key);
     698
     699        $key = str_repeat("\xff", 8) . str_repeat("\x00", 8);
     700        $this->shorthashVerify($message, $key);
     701
     702        $message = str_repeat("\x00", 8);
     703        $key = random_bytes(16);
     704
     705        $this->shorthashVerify($message, $key);
     706
     707        $message = random_bytes(random_int(1, 100));
     708        $this->shorthashVerify($message, $key);
     709    }
     710   
     711    protected function shorthashVerify($m, $k)
     712    {
     713        $this->assertSame(
     714            bin2hex(\Sodium\crypto_shorthash($m, $k)),
     715            bin2hex(ParagonIE_Sodium_Compat::crypto_shorthash($m, $k))
     716        );
     717    }
     718}
  • wp-includes/sodium_compat/tests/unit/UtilTest.php

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
     1<?php
     2
     3class UtilTest extends PHPUnit_Framework_TestCase
     4{
     5    public function setUp()
     6    {
     7        ParagonIE_Sodium_Compat::$disableFallbackForUnitTests = true;
     8    }
     9
     10    /**
     11     * @covers ParagonIE_Sodium_Core_Util::bin2hex()
     12     * @covers ParagonIE_Sodium_Core_Util::hex2bin()
     13     */
     14    public function testBin2hex()
     15    {
     16        $data = random_bytes(32);
     17        $this->assertSame(
     18            bin2hex($data),
     19            ParagonIE_Sodium_Core_Util::bin2hex($data),
     20            'bin2hex should be the compatible with PHP'
     21        );
     22        $this->assertSame(
     23            $data,
     24            ParagonIE_Sodium_Core_Util::hex2bin(
     25                ParagonIE_Sodium_Core_Util::bin2hex($data)
     26            ),
     27            'bin2hex and hex2bin should decode a string to itself'
     28        );
     29        $this->assertSame(
     30            $data,
     31            ParagonIE_Sodium_Core_Util::hex2bin(
     32                bin2hex($data)
     33            ),
     34            'hex2bin should be compatible with PHP'
     35        );
     36    }
     37
     38    /**
     39     * @covers ParagonIE_Sodium_Compat::randombytes_buf()
     40     * @covers ParagonIE_Sodium_Compat::randombytes_random16()
     41     * @covers ParagonIE_Sodium_Compat::randombytes_uniform()
     42     */
     43    public function testRandombytes()
     44    {
     45        $random = ParagonIE_Sodium_Compat::randombytes_buf(32);
     46        $this->assertSame(32, ParagonIE_Sodium_Core_Util::strlen($random));
     47
     48        $other = ParagonIE_Sodium_Compat::randombytes_buf(32);
     49        $this->assertNotSame($random, $other);
     50
     51        $int = ParagonIE_Sodium_Compat::randombytes_uniform(1000);
     52        $this->assertLessThan(1000, $int, 'Out of bounds (> 1000)');
     53        $this->assertGreaterThan(0, $int, 'Out of bounds (< 0)');
     54
     55        $int = ParagonIE_Sodium_Compat::randombytes_random16();
     56        $this->assertLessThan(65536, $int, 'Out of bounds (> 65535)');
     57        $this->assertGreaterThan(0, $int, 'Out of bounds (< 0)');
     58    }
     59
     60    /**
     61     * @covers ParagonIE_Sodium_Core_Util::intArrayToString()
     62     * @covers ParagonIE_Sodium_Core_Util::stringToIntArray()
     63     */
     64    public function testConversion()
     65    {
     66        $sample = array(80, 97, 114, 97, 103, 111, 110);
     67
     68        $this->assertSame(
     69            'Paragon',
     70            ParagonIE_Sodium_Core_Util::intArrayToString($sample)
     71        );
     72
     73        $this->assertSame(
     74            $sample,
     75            ParagonIE_Sodium_Core_Util::stringToIntArray('Paragon')
     76        );
     77
     78    }
     79
     80    /**
     81     * @covers ParagonIE_Sodium_Core_Util::load_3()
     82     */
     83    public function testLoad3()
     84    {
     85        $this->assertSame(
     86            8451279,
     87            ParagonIE_Sodium_Core_Curve25519::load_3("\xcf\xf4\x80"),
     88            'Unexpected result from load_3'
     89        );
     90        $this->assertSame(
     91            8516815,
     92            ParagonIE_Sodium_Core_Curve25519::load_3("\xcf\xf4\x81"),
     93            'Verify endianness is correct'
     94        );
     95        $this->assertSame(
     96            8451280,
     97            ParagonIE_Sodium_Core_Curve25519::load_3("\xd0\xf4\x80"),
     98            'Verify endianness is correct'
     99        );
     100    }
     101
     102    /**
     103     * @covers ParagonIE_Sodium_Core_Util::load_3()
     104     */
     105    public function testLoad4()
     106    {
     107        $this->assertSame(
     108            8451279,
     109            ParagonIE_Sodium_Core_Curve25519::load_4("\xcf\xf4\x80\x00"),
     110            'Unexpected result from load_4'
     111        );
     112        $this->assertSame(
     113            2163527424,
     114            ParagonIE_Sodium_Core_Curve25519::load_4("\x00\xcf\xf4\x80"),
     115            'Unexpected result from load_4'
     116        );
     117    }
     118
     119    /**
     120     * @covers ParagonIE_Sodium_Core_Util::strlen()
     121     */
     122    public function testStrlen()
     123    {
     124        $this->assertSame(4, ParagonIE_Sodium_Core_Util::strlen("\xF0\x9D\x92\xB3"));
     125    }
     126
     127    /**
     128     * @covers ParagonIE_Sodium_Core_Util::strlen()
     129     */
     130    public function testSubstr()
     131    {
     132        $string = \str_repeat("\xF0\x9D\x92\xB3", 4);
     133        $this->assertSame(ParagonIE_Sodium_Core_Util::substr($string, 0, 1), "\xF0");
     134        $this->assertSame(ParagonIE_Sodium_Core_Util::substr($string, 1, 1), "\x9D");
     135        $this->assertSame(ParagonIE_Sodium_Core_Util::substr($string, 2, 1), "\x92");
     136        $this->assertSame(ParagonIE_Sodium_Core_Util::substr($string, 3, 1), "\xB3");
     137        $this->assertSame(ParagonIE_Sodium_Core_Util::substr($string, 0, 2), "\xF0\x9D");
     138        $this->assertSame(ParagonIE_Sodium_Core_Util::substr($string, 2, 2), "\x92\xB3");
     139    }
     140}
  • wp-includes/sodium_compat/src/Core/Curve25519/Ge/P1p1.php

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
     1<?php
     2
     3/**
     4 * Class ParagonIE_Sodium_Core_Curve25519_Ge_P1p1
     5 */
     6class ParagonIE_Sodium_Core_Curve25519_Ge_P1p1
     7{
     8    /**
     9     * @var ParagonIE_Sodium_Core_Curve25519_Fe
     10     */
     11    public $X;
     12
     13    /**
     14     * @var ParagonIE_Sodium_Core_Curve25519_Fe
     15     */
     16    public $Y;
     17
     18    /**
     19     * @var ParagonIE_Sodium_Core_Curve25519_Fe
     20     */
     21    public $Z;
     22
     23    /**
     24     * @var ParagonIE_Sodium_Core_Curve25519_Fe
     25     */
     26    public $T;
     27
     28    /**
     29     * ParagonIE_Sodium_Core_Curve25519_Ge_P1p1 constructor.
     30     * @param ParagonIE_Sodium_Core_Curve25519_Fe $x
     31     * @param ParagonIE_Sodium_Core_Curve25519_Fe $y
     32     * @param ParagonIE_Sodium_Core_Curve25519_Fe $z
     33     * @param ParagonIE_Sodium_Core_Curve25519_Fe $t
     34     */
     35    public function __construct(
     36        ParagonIE_Sodium_Core_Curve25519_Fe $x = null,
     37        ParagonIE_Sodium_Core_Curve25519_Fe $y = null,
     38        ParagonIE_Sodium_Core_Curve25519_Fe $z = null,
     39        ParagonIE_Sodium_Core_Curve25519_Fe $t = null
     40    ) {
     41        $this->X = $x;
     42        $this->Y = $y;
     43        $this->Z = $z;
     44        $this->T = $t;
     45    }
     46}
  • wp-includes/sodium_compat/autoload.php

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
     1<?php
     2
     3/**
     4 * @param string $class
     5 * @return bool
     6 */
     7function sodiumCompatAutoader($class)
     8{
     9    $namespace = 'ParagonIE_Sodium_';
     10    // does the class use the namespace prefix?
     11    $len = strlen($namespace);
     12    if (strncmp($namespace, $class, $len) !== 0) {
     13        // no, move to the next registered autoloader
     14        return false;
     15    }
     16    // get the relative class name
     17    $relative_class = substr($class, $len);
     18    // replace the namespace prefix with the base directory, replace namespace
     19    // separators with directory separators in the relative class name, append
     20    // with .php
     21    $file = __DIR__ . '/src/' . str_replace('_', '/', $relative_class) . '.php';
     22    // if the file exists, require it
     23    if (file_exists($file)) {
     24        require $file;
     25        return true;
     26    }
     27    return false;
     28}
     29spl_autoload_register('sodiumCompatAutoader');
     30
     31if (PHP_VERSION_ID >= 50300) {
     32    // Namespaces didn't exist before 5.3.0, so don't even try to use this
     33    // unless PHP >= 5.3.0
     34    require_once __DIR__ . '/lib/sodium_compat.php';
     35}
  • wp-includes/sodium_compat/src/Core/BLAKE2b.php

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
     1<?php
     2
     3/**
     4 * Class ParagonIE_Sodium_Core_BLAKE2b
     5 *
     6 * Based on the work of Devi Mandiri in devi/salt.
     7 */
     8abstract class ParagonIE_Sodium_Core_BLAKE2b extends ParagonIE_Sodium_Core_Util
     9{
     10    /**
     11     * @var SplFixedArray[]
     12     */
     13    protected static $iv;
     14
     15    /**
     16     * @var int[][]
     17     */
     18    protected static $sigma = array(
     19        array(  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15),
     20        array( 14, 10,  4,  8,  9, 15, 13,  6,  1, 12,  0,  2, 11,  7,  5,  3),
     21        array( 11,  8, 12,  0,  5,  2, 15, 13, 10, 14,  3,  6,  7,  1,  9,  4),
     22        array(  7,  9,  3,  1, 13, 12, 11, 14,  2,  6,  5, 10,  4,  0, 15,  8),
     23        array(  9,  0,  5,  7,  2,  4, 10, 15, 14,  1, 11, 12,  6,  8,  3, 13),
     24        array(  2, 12,  6, 10,  0, 11,  8,  3,  4, 13,  7,  5, 15, 14,  1,  9),
     25        array( 12,  5,  1, 15, 14, 13,  4, 10,  0,  7,  6,  3,  9,  2,  8, 11),
     26        array( 13, 11,  7, 14, 12,  1,  3,  9,  5,  0, 15,  4,  8,  6,  2, 10),
     27        array(  6, 15, 14,  9, 11,  3,  0,  8, 12,  2, 13,  7,  1,  4, 10,  5),
     28        array( 10,  2,  8,  4,  7,  6,  1,  5, 15, 11,  9, 14,  3, 12, 13 , 0),
     29        array(  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15),
     30        array( 14, 10,  4,  8,  9, 15, 13,  6,  1, 12,  0,  2, 11,  7,  5,  3)
     31    );
     32
     33    const BLOCKBYTES = 128;
     34    const OUTBYTES   = 64;
     35    const KEYBYTES   = 64;
     36
     37    /**
     38     * Turn two 32-bit integers into a fixed array representing a 64-bit integer.
     39     *
     40     * @param int $high
     41     * @param int $low
     42     * @return SplFixedArray
     43     */
     44    protected static function new64($high, $low)
     45    {
     46        $i64 = new SplFixedArray(2);
     47        $i64[0] = $high & 0xffffffff;
     48        $i64[1] = $low & 0xffffffff;
     49        return $i64;
     50    }
     51
     52    /**
     53     * Convert an arbitrary number into an SplFixedArray of two 32-bit integers
     54     * that represents a 64-bit integer.
     55     *
     56     * @param int $num
     57     * @return SplFixedArray
     58     */
     59    protected static function to64($num)
     60    {
     61        $hi = 0; $lo = $num & 0xffffffff;
     62
     63        if ((+(abs($num))) >= 1) {
     64            if ($num > 0) {
     65                $hi = min((+(floor($num/4294967296))), 4294967295);
     66            } else {
     67                $hi = ~~((+(ceil(($num - (+((~~($num)))))/4294967296))));
     68            }
     69        }
     70
     71        return self::new64($hi, $lo);
     72    }
     73
     74    /**
     75     * Adds two 64-bit integers together, returning their sum as a SplFixedArray
     76     * containing two 32-bit integers (representing a 64-bit integer).
     77     *
     78     * @param SplFixedArray $x
     79     * @param SplFixedArray $y
     80     * @return SplFixedArray
     81     */
     82    protected static function add64($x, $y)
     83    {
     84        $l = ($x[1] + $y[1]) & 0xffffffff;
     85        return self::new64($x[0] + $y[0] + (($l < $x[1]) ? 1 : 0), $l);
     86    }
     87
     88    /**
     89     * @param SplFixedArray $x
     90     * @param SplFixedArray $y
     91     * @param SplFixedArray $z
     92     * @return SplFixedArray
     93     */
     94    protected static function add364($x, $y, $z)
     95    {
     96        return self::add64($x, self::add64($y, $z));
     97    }
     98
     99    /**
     100     * @param SplFixedArray $x
     101     * @param SplFixedArray $y
     102     * @return SplFixedArray
     103     * @throws Exception
     104     */
     105    protected static function xor64(SplFixedArray $x, SplFixedArray $y)
     106    {
     107        if (!is_numeric($x[0])) {
     108            throw new Exception('x[0] is not an integer');
     109        }
     110        if (!is_numeric($x[1])) {
     111            throw new Exception('x[1] is not an integer');
     112        }
     113        if (!is_numeric($y[0])) {
     114            throw new Exception('y[0] is not an integer');
     115        }
     116        if (!is_numeric($y[1])) {
     117            throw new Exception('y[1] is not an integer');
     118        }
     119        return self::new64($x[0] ^ $y[0], $x[1] ^ $y[1]);
     120    }
     121
     122    /**
     123     * @param SplFixedArray $x
     124     * @param int $c
     125     * @return SplFixedArray
     126     */
     127    protected static function rotr64($x, $c)
     128    {
     129        $l0 = 0;
     130        $c = 64 - $c;
     131
     132        if ($c < 32) {
     133            $h0 = ($x[0] << $c) | (($x[1] & ((1 << $c) - 1) << (32 - $c)) >> (32 - $c));
     134            $l0 = $x[1] << $c;
     135        } else {
     136            $h0 = $x[1] << ($c - 32);
     137        }
     138
     139        $h1 = 0;
     140        $c1 = 64 - $c;
     141
     142        if ($c1 < 32) {
     143            $h1 = $x[0] >> $c1;
     144            $l1 = ($x[1] >> $c1) | ($x[0] & ((1 << $c1) - 1)) << (32 - $c1);
     145        } else {
     146            $l1 = $x[0] >> ($c1 - 32);
     147        }
     148
     149        return self::new64($h0 | $h1, $l0 | $l1);
     150    }
     151
     152    /**
     153     * @param SplFixedArray $x
     154     * @return int
     155     */
     156    protected static function flatten64($x)
     157    {
     158        return ($x[0] * 4294967296 + $x[1]);
     159    }
     160
     161    /**
     162     * @param $x
     163     * @param $i
     164     * @return SplFixedArray
     165     */
     166    protected static function load64($x, $i)
     167    {
     168        $l = $x[$i]   | ($x[$i+1]<<8) | ($x[$i+2]<<16) | ($x[$i+3]<<24);
     169        $h = $x[$i+4] | ($x[$i+5]<<8) | ($x[$i+6]<<16) | ($x[$i+7]<<24);
     170        return self::new64($h, $l);
     171    }
     172
     173    /**
     174     * @param $x
     175     * @param $i
     176     * @param $u
     177     */
     178    protected static function store64($x, $i, $u)
     179    {
     180        $x[$i]   = ($u[1] & 0xff); $u[1] >>= 8;
     181        $x[$i+1] = ($u[1] & 0xff); $u[1] >>= 8;
     182        $x[$i+2] = ($u[1] & 0xff); $u[1] >>= 8;
     183        $x[$i+3] = ($u[1] & 0xff);
     184        $x[$i+4] = ($u[0] & 0xff); $u[0] >>= 8;
     185        $x[$i+5] = ($u[0] & 0xff); $u[0] >>= 8;
     186        $x[$i+6] = ($u[0] & 0xff); $u[0] >>= 8;
     187        $x[$i+7] = ($u[0] & 0xff);
     188    }
     189
     190    /**
     191     * This just sets the $iv static variable.
     192     */
     193    public static function pseudoConstructor()
     194    {
     195        static $called = false;
     196        if ($called) {
     197            return;
     198        }
     199        self::$iv = new SplFixedArray(8);
     200        self::$iv[0] = self::new64(0x6a09e667, 0xf3bcc908);
     201        self::$iv[1] = self::new64(0xbb67ae85, 0x84caa73b);
     202        self::$iv[2] = self::new64(0x3c6ef372, 0xfe94f82b);
     203        self::$iv[3] = self::new64(0xa54ff53a, 0x5f1d36f1);
     204        self::$iv[4] = self::new64(0x510e527f, 0xade682d1);
     205        self::$iv[5] = self::new64(0x9b05688c, 0x2b3e6c1f);
     206        self::$iv[6] = self::new64(0x1f83d9ab, 0xfb41bd6b);
     207        self::$iv[7] = self::new64(0x5be0cd19, 0x137e2179);
     208
     209        $called = true;
     210    }
     211
     212    /**
     213     * Returns a fresh BLAKE2 context.
     214     *
     215     * @return SplFixedArray
     216     */
     217    protected static function context()
     218    {
     219        $ctx    = new SplFixedArray(5);
     220        $ctx[0] = new SplFixedArray(8);   // h
     221        $ctx[1] = new SplFixedArray(2);   // t
     222        $ctx[2] = new SplFixedArray(2);   // f
     223        $ctx[3] = new SplFixedArray(256); // buf
     224        $ctx[4] = 0;                      // buflen
     225
     226        for ($i = 8; $i--;) {
     227            $ctx[0][$i] = self::$iv[$i];
     228        }
     229        for ($i = 256; $i--;) {
     230            $ctx[3][$i] = 0;
     231        }
     232
     233        $zero = self::new64(0, 0);
     234        $ctx[1][0] = $zero;
     235        $ctx[1][1] = $zero;
     236        $ctx[2][0] = $zero;
     237        $ctx[2][1] = $zero;
     238
     239        return $ctx;
     240    }
     241
     242    /**
     243     * @param SplFixedArray $ctx
     244     * @param SplFixedArray $buf
     245     */
     246    protected static function compress(SplFixedArray $ctx, SplFixedArray $buf)
     247    {
     248        $m = new SplFixedArray(16);
     249        $v = new SplFixedArray(16);
     250
     251        for ($i = 16; $i--;) {
     252            $m[$i] = self::load64($buf, $i*8);
     253        }
     254
     255        for ($i = 8; $i--;) {
     256            $v[$i] = $ctx[0][$i];
     257        }
     258
     259        $v[ 8] = self::$iv[0];
     260        $v[ 9] = self::$iv[1];
     261        $v[10] = self::$iv[2];
     262        $v[11] = self::$iv[3];
     263
     264        $v[12] = self::xor64($ctx[1][0], self::$iv[4]);
     265        $v[13] = self::xor64($ctx[1][1], self::$iv[5]);
     266        $v[14] = self::xor64($ctx[2][0], self::$iv[6]);
     267        $v[15] = self::xor64($ctx[2][1], self::$iv[7]);
     268
     269        for ($r = 0; $r < 12; ++$r) {
     270            $v = self::G($r, 0,  0,  4,  8, 12, $v, $m);
     271            $v = self::G($r, 1,  1,  5,  9, 13, $v, $m);
     272            $v = self::G($r, 2,  2,  6, 10, 14, $v, $m);
     273            $v = self::G($r, 3,  3,  7, 11, 15, $v, $m);
     274            $v = self::G($r, 4,  0,  5, 10, 15, $v, $m);
     275            $v = self::G($r, 5,  1,  6, 11, 12, $v, $m);
     276            $v = self::G($r, 6,  2,  7,  8, 13, $v, $m);
     277            $v = self::G($r, 7,  3,  4,  9, 14, $v, $m);
     278        }
     279
     280        for ($i = 8; $i--;) {
     281            $ctx[0][$i] = self::xor64(
     282                $ctx[0][$i], self::xor64($v[$i], $v[$i+8])
     283            );
     284        }
     285    }
     286
     287    /**
     288     * @param int $r
     289     * @param int $i
     290     * @param int $a
     291     * @param int $b
     292     * @param int $c
     293     * @param int $d
     294     * @param SplFixedArray $v
     295     * @param SplFixedArray $m
     296     * @return SplFixedArray
     297     */
     298    public static function G($r, $i, $a, $b, $c, $d, SplFixedArray $v, SplFixedArray $m)
     299    {
     300        $v[$a] = self::add364($v[$a], $v[$b], $m[self::$sigma[$r][2*$i]]);
     301        $v[$d] = self::rotr64(self::xor64($v[$d], $v[$a]), 32);
     302        $v[$c] = self::add64($v[$c], $v[$d]);
     303        $v[$b] = self::rotr64(self::xor64($v[$b], $v[$c]), 24);
     304        $v[$a] = self::add364($v[$a], $v[$b], $m[self::$sigma[$r][2*$i+1]]);
     305        $v[$d] = self::rotr64(self::xor64($v[$d], $v[$a]), 16);
     306        $v[$c] = self::add64($v[$c], $v[$d]);
     307        $v[$b] = self::rotr64(self::xor64($v[$b], $v[$c]), 63);
     308        return $v;
     309    }
     310
     311    /**
     312     * @param SplFixedArray $ctx
     313     * @param int $inc
     314     */
     315    protected static function increment_counter($ctx, $inc)
     316    {
     317        $t = self::to64($inc);
     318        $ctx[1][0] = self::add64($ctx[1][0], $t);
     319        if (self::flatten64($ctx[1][0]) < $inc) {
     320            $ctx[1][1] = self::add64($ctx[1][1], self::to64(1));
     321        }
     322    }
     323
     324    /**
     325     * @param SplFixedArray $ctx
     326     * @param SplFixedArray $p
     327     * @param int $plen
     328     */
     329    public static function update(SplFixedArray $ctx, $p, $plen)
     330    {
     331        $offset = 0;
     332        while ($plen > 0) {
     333            $left = $ctx[4];
     334            $fill = 256 - $left;
     335
     336            if ($plen > $fill) {
     337                for ($i = $fill; $i--;) {
     338                    $ctx[3][$i+$left] = $p[$i+$offset];
     339                }
     340
     341                $ctx[4] += $fill;
     342
     343                self::increment_counter($ctx, 128);
     344                self::compress($ctx, $ctx[3]);
     345
     346                for ($i = 128; $i--;) {
     347                    $ctx[3][$i] = $ctx[3][$i+128];
     348                }
     349
     350                $ctx[4] -= 128;
     351                $offset += $fill;
     352                $plen -= $fill;
     353            } else {
     354                for ($i = $plen; $i--;) {
     355                    $ctx[3][$i+$left] = $p[$i+$offset];
     356                }
     357                $ctx[4] += $plen;
     358                $offset += $plen;
     359                $plen -= $plen;
     360            }
     361        }
     362    }
     363
     364    /**
     365     * @param SplFixedArray $ctx
     366     * @param SplFixedArray $out
     367     * @return SplFixedArray
     368     */
     369    public static function finish(SplFixedArray $ctx, SplFixedArray $out)
     370    {
     371        if ($ctx[4] > 128) {
     372            self::increment_counter($ctx, 128);
     373            self::compress($ctx, $ctx[3]);
     374            $ctx[4] -= 128;
     375            for ($i = $ctx[4]; $i--;) {
     376                $ctx[3][$i] = $ctx[3][$i+128];
     377            }
     378        }
     379
     380        self::increment_counter($ctx, $ctx[4]);
     381        $ctx[2][0] = self::new64(0xffffffff, 0xffffffff);
     382
     383        for ($i = 256 - $ctx[4]; $i--;) {
     384            $ctx[3][$i+$ctx[4]] = 0;
     385        }
     386
     387        self::compress($ctx, $ctx[3]);
     388
     389        $i = (int) (($out->getSize() - 1) / 8);
     390        for (; $i >= 0; --$i) {
     391            self::store64($out, $i * 8, $ctx[0][$i]);
     392        }
     393        return $out;
     394    }
     395
     396    /**
     397     * @param SplFixedArray|null $key
     398     * @param int $outlen
     399     * @return SplFixedArray
     400     * @throws Exception
     401     */
     402    public static function init($key = null, $outlen = 64)
     403    {
     404        $klen = 0;
     405
     406        if ($key !== null) {
     407            if (count($key) > 64) {
     408                throw new Exception('Invalid key size');
     409            }
     410            $klen = count($key);
     411        }
     412
     413        if ($outlen > 64) {
     414            throw new Exception('Invalid output size');
     415        }
     416
     417        $ctx = self::context();
     418
     419        $p = new SplFixedArray(64);
     420        for ($i = 64; --$i;) $p[$i] = 0;
     421
     422        $p[0] = $outlen; // digest_length
     423        $p[1] = $klen;   // key_length
     424        $p[2] = 1;       // fanout
     425        $p[3] = 1;       // depth
     426
     427        $ctx[0][0] = self::xor64(
     428            $ctx[0][0],
     429            self::load64($p, 0)
     430        );
     431
     432        if ($klen > 0) {
     433            $block = new SplFixedArray(128);
     434            for ($i = 128; $i--;) {
     435                $block[$i] = 0;
     436            }
     437            for ($i = $klen; $i--;) {
     438                $block[$i] = $key[$i];
     439            }
     440            self::update($ctx, $block, 128);
     441        }
     442
     443        return $ctx;
     444    }
     445
     446    /**
     447     * Convert a string into an SplFixedArray of integers
     448     *
     449     * @param string $str
     450     * @return SplFixedArray
     451     */
     452    public static function stringToSplFixedArray($str = '')
     453    {
     454        $values = unpack('C*', $str);
     455        return SplFixedArray::fromArray(array_values($values));
     456    }
     457
     458    /**
     459     * Convert an SplFixedArray of integers into a string
     460     *
     461     * @param SplFixedArray $a
     462     * @return string
     463     */
     464    public static function SplFixedArrayToString(SplFixedArray $a)
     465    {
     466        $arr = $a->toArray();
     467        $c = $a->count();
     468        array_unshift($arr, str_repeat('C', $c));
     469        return call_user_func_array('pack', $arr);
     470    }
     471
     472    /**
     473     * @param SplFixedArray[SplFixedArray] $ctx
     474     * @return string
     475     */
     476    public static function contextToString(SplFixedArray $ctx)
     477    {
     478        $str = '';
     479        $ctxA = $ctx[0]->toArray();
     480        for ($i = 0; $i < 8; ++$i) {
     481            $str .= self::store32_le($ctxA[$i][1]);
     482            $str .= self::store32_le($ctxA[$i][0]);
     483        }
     484        for ($i = 0; $i < 2; ++$i) {
     485            $ctxA = $ctx[$i + 1]->toArray();
     486            $str .= self::store32_le($ctxA[0][1]);
     487            $str .= self::store32_le($ctxA[0][0]);
     488            $str .= self::store32_le($ctxA[1][1]);
     489            $str .= self::store32_le($ctxA[1][0]);
     490        }
     491        $str .= self::SplFixedArrayToString($ctx[3]);
     492        $str .= implode('', array(
     493            self::intToChr($ctx[4] & 0xff),
     494            self::intToChr(($ctx[4] << 8) & 0xff),
     495            self::intToChr(($ctx[4] << 16) & 0xff),
     496            self::intToChr(($ctx[4] << 24) & 0xff),
     497            self::intToChr(($ctx[4] << 32) & 0xff),
     498            self::intToChr(($ctx[4] << 40) & 0xff),
     499            self::intToChr(($ctx[4] << 48) & 0xff),
     500            self::intToChr(($ctx[4] << 56) & 0xff)
     501        ));
     502        return $str . "\x00";
     503    }
     504
     505    /**
     506     * Creates an SplFixedArray containing other SplFixedArray elements, from
     507     * a string (compatible with \Sodium\crypto_generichash_{init, update, final})
     508     *
     509     * @param $string
     510     * @return SplFixedArray
     511     */
     512    public static function stringToContext($string)
     513    {
     514        $ctx = self::context();
     515        for ($i = 0; $i < 8; ++$i) {
     516            $ctx[0][$i] = SplFixedArray::fromArray(
     517                array(
     518                    self::load_4(
     519                        self::substr($string, (8 * $i + 4), 4)
     520                    ),
     521                    self::load_4(
     522                        self::substr($string, (8 * $i + 0), 4)
     523                    )
     524                )
     525            );
     526        }
     527        for ($i = 1; $i <= 2; ++$i) {
     528            $ctx[$i][0] = SplFixedArray::fromArray(
     529                array(
     530                    self::load_4(self::substr($string, 64 + (8 * $i), 4)),
     531                    self::load_4(self::substr($string, 60 + (8 * $i), 4))
     532                )
     533            );
     534        }
     535        $ctx[3] = self::stringToSplFixedArray(self::substr($string, 96, 256));
     536        $int = 0;
     537        for ($i = 0; $i < 8; ++$i) {
     538            $int |= self::chrToInt($string[352 + $i]) << (8 * $i);
     539        }
     540        $ctx[4] = $int;
     541        return $ctx;
     542    }
     543}
  • wp-includes/sodium_compat/src/Core/Ed25519.php

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
     1<?php
     2
     3/**
     4 * Class ParagonIE_Sodium_Core_Ed25519
     5 */
     6abstract class ParagonIE_Sodium_Core_Ed25519 extends ParagonIE_Sodium_Core_Curve25519
     7{
     8    const KEYPAIR_BYTES = 96;
     9    const SEED_BYTES = 32;
     10
     11    /**
     12     * @return string (96 bytes)
     13     */
     14    public static function keypair()
     15    {
     16        $seed = random_bytes(self::SEED_BYTES);
     17        $pk = '';
     18        $sk = '';
     19        self::seed_keypair($pk, $sk, $seed);
     20        return $sk . $pk;
     21    }
     22
     23    /**
     24     * @param string $pk
     25     * @param string $sk
     26     * @param string $seed
     27     */
     28    public static function seed_keypair(&$pk, &$sk, $seed)
     29    {
     30        if (self::strlen($seed) !== self::SEED_BYTES) {
     31            throw new RangeException('crypto_sign keypair seed must be 32 bytes long');
     32        }
     33        $pk = self::publickey_from_secretkey($seed);
     34        $sk = self::substr($seed, 0, self::SEED_BYTES) . $pk;
     35    }
     36
     37    /**
     38     * @param string $keypair
     39     * @return string
     40     */
     41    public static function secretkey($keypair)
     42    {
     43        if (self::strlen($keypair) !== self::KEYPAIR_BYTES) {
     44            throw new RangeException('crypto_sign keypair seed must be 32 bytes long');
     45        }
     46        return self::substr($keypair, 0, 64);
     47    }
     48
     49    /**
     50     * @param string $keypair
     51     * @return string
     52     */
     53    public static function publickey($keypair)
     54    {
     55        if (self::strlen($keypair) !== self::KEYPAIR_BYTES) {
     56            throw new RangeException('crypto_sign keypair seed must be 32 bytes long');
     57        }
     58        return self::substr($keypair, 64, 32);
     59    }
     60
     61    /**
     62     * @param $sk
     63     * @return string
     64     */
     65    public static function publickey_from_secretkey($sk)
     66    {
     67        $sk = hash('sha512', self::substr($sk, 0, 32), true);
     68        $sk[0] = self::intToChr(
     69            self::chrToInt($sk[0]) & 248
     70        );
     71        $sk[31] = self::intToChr(
     72            (self::chrToInt($sk[31]) & 63) | 64
     73        );
     74        return self::sk_to_pk($sk);
     75    }
     76
     77    /**
     78     * @param $sk
     79     * @return string
     80     */
     81    public static function sk_to_pk($sk)
     82    {
     83        return self::ge_p3_tobytes(
     84            self::ge_scalarmult_base(self::substr($sk, 0, 32))
     85        );
     86    }
     87
     88    /**
     89     * @param string $message
     90     * @param string $sk
     91     * @return string
     92     */
     93    public static function sign($message, $sk)
     94    {
     95        $signature = self::sign_detached($message, $sk);
     96        return $signature . $message;
     97    }
     98
     99    /**
     100     * @param string $message
     101     * @param string $pk
     102     * @return string
     103     * @throws Exception
     104     */
     105    public static function sign_open($message, $pk)
     106    {
     107        $signature = self::substr($message, 0, 64);
     108        $message = self::substr($message, 64);
     109        if (self::verify_detached($signature, $message, $pk)) {
     110            return $message;
     111        }
     112        throw new Exception('Invalid signature');
     113    }
     114
     115    /**
     116     * @param string $message
     117     * @param string $sk
     118     * @return string
     119     */
     120    public static function sign_detached($message, $sk)
     121    {
     122        # crypto_hash_sha512(az, sk, 32);
     123        $az =  hash('sha512', self::substr($sk, 0, 32), true);
     124
     125        # az[0] &= 248;
     126        # az[31] &= 63;
     127        # az[31] |= 64;
     128        $az[0] = self::intToChr(self::chrToInt($az[0]) & 248);
     129        $az[31] = self::intToChr((self::chrToInt($az[31]) & 63) | 64);
     130
     131        # crypto_hash_sha512_init(&hs);
     132        # crypto_hash_sha512_update(&hs, az + 32, 32);
     133        # crypto_hash_sha512_update(&hs, m, mlen);
     134        # crypto_hash_sha512_final(&hs, nonce);
     135        $hs = hash_init('sha512');
     136        hash_update($hs, self::substr($az, 32, 32));
     137        hash_update($hs, $message);
     138        $nonceHash = hash_final($hs, true);
     139
     140        # memmove(sig + 32, sk + 32, 32);
     141        $pk = self::substr($sk, 32, 32);
     142
     143        # sc_reduce(nonce);
     144        # ge_scalarmult_base(&R, nonce);
     145        # ge_p3_tobytes(sig, &R);
     146        $nonce = self::sc_reduce($nonceHash) . self::substr($nonceHash, 32);
     147        $sig = self::ge_p3_tobytes(
     148            self::ge_scalarmult_base($nonce)
     149        );
     150
     151        # crypto_hash_sha512_init(&hs);
     152        # crypto_hash_sha512_update(&hs, sig, 64);
     153        # crypto_hash_sha512_update(&hs, m, mlen);
     154        # crypto_hash_sha512_final(&hs, hram);
     155        $hs = hash_init('sha512');
     156        hash_update($hs, $sig);
     157        hash_update($hs, $pk);
     158        hash_update($hs, $message);
     159        $hramHash = hash_final($hs, true);
     160
     161        # sc_reduce(hram);
     162        # sc_muladd(sig + 32, hram, az, nonce);
     163        $hram = self::sc_reduce($hramHash);
     164        $sigAfter = self::sc_muladd($hram, $az, $nonce);
     165        $sig = self::substr($sig, 0, 32) . self::substr($sigAfter, 0, 32);
     166
     167        ParagonIE_Sodium_Compat::memzero($az);
     168        return $sig;
     169    }
     170
     171    /**
     172     * @param string $sig
     173     * @param string $message
     174     * @param string $pk
     175     * @return bool
     176     * @throws Exception
     177     */
     178    public static function verify_detached($sig, $message, $pk)
     179    {
     180        if (self::strlen($sig) < 64) {
     181            throw new Exception('Signature is too short');
     182        }
     183        if (self::check_S_lt_L(self::substr($sig, 32, 32))) {
     184            throw new Exception('S < L - Invalid signature');
     185        }
     186        if (self::small_order($sig)) {
     187            throw new Exception('Signature is on too small of an order');
     188        }
     189        if ((self::chrToInt($sig[63]) & 224) !== 0) {
     190            throw new Exception('Invalid signature');
     191        }
     192
     193        $A = self::ge_frombytes_negate_vartime($pk);
     194        $d = 0;
     195        for ($i = 0; $i < 32; ++$i) {
     196            $d |= self::chrToInt($pk[$i]);
     197        }
     198        if ($d === 0) {
     199            throw new \Exception('All zero public key');
     200        }
     201
     202        $hDigest = hash('sha512', self::substr($sig, 0, 32) . $pk . $message, true);
     203        $h = self::sc_reduce($hDigest) . self::substr($hDigest, 32);
     204        $R = self::ge_double_scalarmult_vartime(
     205            $h,
     206            $A,
     207            self::substr($sig, 32)
     208        );
     209        $rcheck = self::ge_tobytes($R);
     210        return self::verify_32($rcheck, self::substr($sig, 0, 32));
     211    }
     212
     213    /**
     214     * @param string $S
     215     * @return bool
     216     * @throws Exception
     217     */
     218    public static function check_S_lt_L($S)
     219    {
     220        if (self::strlen($S) < 32) {
     221            throw new Exception('Signature must be 32 bytes');
     222        }
     223        static $L = array(
     224            0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58,
     225            0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14,
     226            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     227            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10
     228        );
     229        $c = 0;
     230        $n = 1;
     231        $i = 32;
     232
     233        do {
     234            --$i;
     235            $x = self::chrToInt($S[$i]);
     236            $c |= (
     237                (($x - $L[$i]) >> 8) & $n
     238            );
     239            $n &= (
     240                (($x ^ $L[$i]) - 1) >> 8
     241            );
     242        } while ($i !== 0);
     243
     244        return $c === 0;
     245    }
     246
     247    /**
     248     * @param string $R
     249     * @return bool
     250     */
     251    public static function small_order($R)
     252    {
     253        static $blacklist = array(
     254            /* 0 (order 4) */
     255            array(
     256                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     257                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     258                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     259                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
     260            ),
     261            /* 1 (order 1) */
     262            array(
     263                0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     264                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     265                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     266                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
     267            ),
     268            /* 2707385501144840649318225287225658788936804267575313519463743609750303402022 (order 8) */
     269            array(
     270                0x26, 0xe8, 0x95, 0x8f, 0xc2, 0xb2, 0x27, 0xb0,
     271                0x45, 0xc3, 0xf4, 0x89, 0xf2, 0xef, 0x98, 0xf0,
     272                0xd5, 0xdf, 0xac, 0x05, 0xd3, 0xc6, 0x33, 0x39,
     273                0xb1, 0x38, 0x02, 0x88, 0x6d, 0x53, 0xfc, 0x05
     274            ),
     275            /* 55188659117513257062467267217118295137698188065244968500265048394206261417927 (order 8) */
     276            array(
     277                0xc7, 0x17, 0x6a, 0x70, 0x3d, 0x4d, 0xd8, 0x4f,
     278                0xba, 0x3c, 0x0b, 0x76, 0x0d, 0x10, 0x67, 0x0f,
     279                0x2a, 0x20, 0x53, 0xfa, 0x2c, 0x39, 0xcc, 0xc6,
     280                0x4e, 0xc7, 0xfd, 0x77, 0x92, 0xac, 0x03, 0x7a
     281            ),
     282            /* p-1 (order 2) */
     283            array(
     284                0x13, 0xe8, 0x95, 0x8f, 0xc2, 0xb2, 0x27, 0xb0,
     285                0x45, 0xc3, 0xf4, 0x89, 0xf2, 0xef, 0x98, 0xf0,
     286                0xd5, 0xdf, 0xac, 0x05, 0xd3, 0xc6, 0x33, 0x39,
     287                0xb1, 0x38, 0x02, 0x88, 0x6d, 0x53, 0xfc, 0x85
     288            ),
     289            /* p (order 4) */
     290            array(
     291                0xb4, 0x17, 0x6a, 0x70, 0x3d, 0x4d, 0xd8, 0x4f,
     292                0xba, 0x3c, 0x0b, 0x76, 0x0d, 0x10, 0x67, 0x0f,
     293                0x2a, 0x20, 0x53, 0xfa, 0x2c, 0x39, 0xcc, 0xc6,
     294                0x4e, 0xc7, 0xfd, 0x77, 0x92, 0xac, 0x03, 0xfa
     295            ),
     296            /* p+1 (order 1) */
     297            array(
     298                0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     299                0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     300                0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     301                0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f
     302            ),
     303            /* p+2707385501144840649318225287225658788936804267575313519463743609750303402022 (order 8) */
     304            array(
     305                0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     306                0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     307                0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     308                0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f
     309            ),
     310            /* p+55188659117513257062467267217118295137698188065244968500265048394206261417927 (order 8) */
     311            array(
     312                0xee, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     313                0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     314                0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     315                0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f
     316            ),
     317            /* 2p-1 (order 2) */
     318            array(
     319                0xd9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     320                0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     321                0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     322                0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
     323            ),
     324            /* 2p (order 4) */
     325            array(
     326                0xda, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     327                0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     328                0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     329                0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
     330            ),
     331            /* 2p+1 (order 1) */
     332            array(
     333                0xdb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     334                0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     335                0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
     336                0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
     337            )
     338        );
     339        $countBlacklist = count($blacklist);
     340
     341        for ($i = 0; $i < $countBlacklist; ++$i) {
     342            $c = 0;
     343            for ($j = 0; $j < 32; ++$j) {
     344                $c |= self::chrToInt($R[$j]) ^ $blacklist[$i][$j];
     345            }
     346            if ($c === 0) {
     347                return true;
     348            }
     349        }
     350        return false;
     351    }
     352}
  • wp-includes/sodium_compat/src/Core/Curve25519/Ge/Precomp.php

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
     1<?php
     2
     3/**
     4 * Class ParagonIE_Sodium_Core_Curve25519_Ge_Precomp
     5 */
     6class ParagonIE_Sodium_Core_Curve25519_Ge_Precomp
     7{
     8    /**
     9     * @var ParagonIE_Sodium_Core_Curve25519_Fe
     10     */
     11    public $yplusx;
     12
     13    /**
     14     * @var ParagonIE_Sodium_Core_Curve25519_Fe
     15     */
     16    public $yminusx;
     17
     18    /**
     19     * @var ParagonIE_Sodium_Core_Curve25519_Fe
     20     */
     21    public $xy2d;
     22
     23    /**
     24     * ParagonIE_Sodium_Core_Curve25519_Ge_Precomp constructor.
     25     * @param ParagonIE_Sodium_Core_Curve25519_Fe $yplusx
     26     * @param ParagonIE_Sodium_Core_Curve25519_Fe $yminusx
     27     * @param ParagonIE_Sodium_Core_Curve25519_Fe $xy2d
     28     */
     29    public function __construct(
     30        ParagonIE_Sodium_Core_Curve25519_Fe $yplusx = null,
     31        ParagonIE_Sodium_Core_Curve25519_Fe $yminusx = null,
     32        ParagonIE_Sodium_Core_Curve25519_Fe $xy2d = null
     33    ) {
     34        $this->yplusx = $yplusx;
     35        $this->yminusx = $yminusx;
     36        $this->xy2d = $xy2d;
     37    }
     38
     39}
     40 No newline at end of file
  • wp-includes/sodium_compat/src/Core/SipHash.php

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
     1<?php
     2
     3/**
     4 * Class ParagonIE_SodiumCompat_Core_SipHash
     5 */
     6class ParagonIE_Sodium_Core_SipHash extends ParagonIE_Sodium_Core_Util
     7{
     8    /**
     9     * @param int[] $v
     10     * @return int[]
     11     */
     12    public static function sipRound(array $v)
     13    {
     14        # v0 += v1;
     15        list($v[0], $v[1]) = self::add(
     16            array($v[0], $v[1]),
     17            array($v[2], $v[3])
     18        );
     19
     20        #  v1=ROTL(v1,13);
     21        list($v[2], $v[3]) = self::rotl_64($v[2], $v[3], 13);
     22
     23        #  v1 ^= v0;
     24        $v[2] ^= $v[0];
     25        $v[3] ^= $v[1];
     26
     27        #  v0=ROTL(v0,32);
     28        list($v[0], $v[1]) = self::rotl_64($v[0], $v[1], 32);
     29
     30        # v2 += v3;
     31        list($v[4], $v[5]) = self::add(
     32            array($v[4], $v[5]),
     33            array($v[6], $v[7])
     34        );
     35
     36        # v3=ROTL(v3,16);
     37        list($v[6], $v[7]) = self::rotl_64($v[6], $v[7], 16);
     38
     39        #  v3 ^= v2;
     40        $v[6] ^= $v[4];
     41        $v[7] ^= $v[5];
     42
     43        # v0 += v3;
     44        list($v[0], $v[1]) = self::add(
     45            array($v[0], $v[1]),
     46            array($v[6], $v[7])
     47        );
     48
     49        # v3=ROTL(v3,21);
     50        list($v[6], $v[7]) = self::rotl_64($v[6], $v[7], 21);
     51
     52        # v3 ^= v0;
     53        $v[6] ^= $v[0];
     54        $v[7] ^= $v[1];
     55
     56        # v2 += v1;
     57        list($v[4], $v[5]) = self::add(
     58            array($v[4], $v[5]),
     59            array($v[2], $v[3])
     60        );
     61
     62        # v1=ROTL(v1,17);
     63        list($v[2], $v[3]) = self::rotl_64($v[2], $v[3], 17);
     64
     65        #  v1 ^= v2;;
     66        $v[2] ^= $v[4];
     67        $v[3] ^= $v[5];
     68
     69        # v2=ROTL(v2,32)
     70        list($v[4], $v[5]) = self::rotl_64($v[4], $v[5], 32);
     71
     72        return $v;
     73    }
     74
     75    /**
     76     * Add two 32 bit integers representing a 64-bit integer.
     77     *
     78     * @param int[] $a
     79     * @param int[] $b
     80     * @return int[]
     81     */
     82    public static function add(array $a, array $b)
     83    {
     84        $x1 = $a[1] + $b[1];
     85        $c = $x1 >> 32; // Carry if ($a + $b) > 0xffffffff
     86        $x0 = $a[0] + $b[0] + $c;
     87        return array(
     88            $x0 & 0xffffffff,
     89            $x1 & 0xffffffff
     90        );
     91    }
     92
     93    /**
     94     * @param int $int0
     95     * @param int $int1
     96     * @param int $c
     97     * @return int[]
     98     */
     99    public static function rotl_64($int0, $int1, $c)
     100    {
     101        $int0 &= 0xffffffff;
     102        $int1 &= 0xffffffff;
     103        $c &= 63;
     104        if ($c === 32) {
     105            return array($int1, $int0);
     106        }
     107        if ($c > 31) {
     108            $tmp = $int1;
     109            $int1 = $int0;
     110            $int0 = $tmp;
     111            $c &= 31;
     112        }
     113        if ($c === 0) {
     114            return array($int0, $int1);
     115        }
     116        return array(
     117            0xffffffff & (
     118                ($int0 << $c)
     119                    |
     120                ($int1 >> (32 - $c))
     121            ),
     122            0xffffffff & (
     123                ($int1 << $c)
     124                    |
     125                ($int0 >> (32 - $c))
     126            ),
     127        );
     128    }
     129
     130    /**
     131     * Implements Siphash-2-4 using only 32-bit numbers.
     132     *
     133     * When we split an int into two, the higher bits go to the lower index.
     134     * e.g. 0xDEADBEEFAB10C92D becomes [
     135     *     0 => 0xDEADBEEF,
     136     *     1 => 0xAB10C92D
     137     * ].
     138     *
     139     * @param string $in
     140     * @param string $key
     141     * @return string
     142     */
     143    public static function sipHash24($in, $key)
     144    {
     145        $inlen = self::strlen($in);
     146
     147        # /* "somepseudorandomlygeneratedbytes" */
     148        # u64 v0 = 0x736f6d6570736575ULL;
     149        # u64 v1 = 0x646f72616e646f6dULL;
     150        # u64 v2 = 0x6c7967656e657261ULL;
     151        # u64 v3 = 0x7465646279746573ULL;
     152        $v = array(
     153            0x736f6d65, // 0
     154            0x70736575, // 1
     155            0x646f7261, // 2
     156            0x6e646f6d, // 3
     157            0x6c796765, // 4
     158            0x6e657261, // 5
     159            0x74656462, // 6
     160            0x79746573  // 7
     161        );
     162        // v0 => $v[0], $v[1]
     163        // v1 => $v[2], $v[3]
     164        // v2 => $v[4], $v[5]
     165        // v3 => $v[6], $v[7]
     166
     167        # u64 k0 = LOAD64_LE( k );
     168        # u64 k1 = LOAD64_LE( k + 8 );
     169        $k = array(
     170            self::load_4(self::substr($key, 4, 4)),
     171            self::load_4(self::substr($key, 0, 4)),
     172            self::load_4(self::substr($key, 12, 4)),
     173            self::load_4(self::substr($key, 8, 4))
     174        );
     175        // k0 => $k[0], $k[1]
     176        // k1 => $k[2], $k[3]
     177
     178        # b = ( ( u64 )inlen ) << 56;
     179        $b = array(
     180            $inlen << 24,
     181            0
     182        );
     183        // See docblock for why the 0th index gets the higher bits.
     184
     185        # v3 ^= k1;
     186        $v[6] ^= $k[2];
     187        $v[7] ^= $k[3];
     188        # v2 ^= k0;
     189        $v[4] ^= $k[0];
     190        $v[5] ^= $k[1];
     191        # v1 ^= k1;
     192        $v[2] ^= $k[2];
     193        $v[3] ^= $k[3];
     194        # v0 ^= k0;
     195        $v[0] ^= $k[0];
     196        $v[1] ^= $k[1];
     197
     198        $left = $inlen;
     199        # for ( ; in != end; in += 8 )
     200        while ($left >= 8) {
     201            # m = LOAD64_LE( in );
     202            $m = array(
     203                self::load_4(self::substr($in, 4, 4)),
     204                self::load_4(self::substr($in, 0, 4))
     205            );
     206
     207            # v3 ^= m;
     208            $v[6] ^= $m[0];
     209            $v[7] ^= $m[1];
     210
     211            # SIPROUND;
     212            # SIPROUND;
     213            $v = self::sipRound($v);
     214            $v = self::sipRound($v);
     215
     216            # v0 ^= m;
     217            $v[0] ^= $m[0];
     218            $v[1] ^= $m[1];
     219
     220            $in = self::substr($in, 8);
     221            $left -= 8;
     222        }
     223
     224        # switch( left )
     225        #  {
     226        #     case 7: b |= ( ( u64 )in[ 6] )  << 48;
     227        #     case 6: b |= ( ( u64 )in[ 5] )  << 40;
     228        #     case 5: b |= ( ( u64 )in[ 4] )  << 32;
     229        #     case 4: b |= ( ( u64 )in[ 3] )  << 24;
     230        #     case 3: b |= ( ( u64 )in[ 2] )  << 16;
     231        #     case 2: b |= ( ( u64 )in[ 1] )  <<  8;
     232        #     case 1: b |= ( ( u64 )in[ 0] ); break;
     233        #     case 0: break;
     234        # }
     235        switch ($left) {
     236            case 7:
     237                $b[0] |= self::chrToInt($in[6]) << 16;
     238            case 6:
     239                $b[0] |= self::chrToInt($in[5]) << 8;
     240            case 5:
     241                $b[0] |= self::chrToInt($in[4]);
     242            case 4:
     243                $b[1] |= self::chrToInt($in[3]) << 24;
     244            case 3:
     245                $b[1] |= self::chrToInt($in[2]) << 16;
     246            case 2:
     247                $b[1] |= self::chrToInt($in[1]) << 8;
     248            case 1:
     249                $b[1] |= self::chrToInt($in[0]);
     250            case 0:
     251                break;
     252        }
     253        // See docblock for why the 0th index gets the higher bits.
     254
     255        # v3 ^= b;
     256        $v[6] ^= $b[0];
     257        $v[7] ^= $b[1];
     258
     259        # SIPROUND;
     260        # SIPROUND;
     261        $v = self::sipRound($v);
     262        $v = self::sipRound($v);
     263
     264        # v0 ^= b;
     265        $v[0] ^= $b[0];
     266        $v[1] ^= $b[1];
     267
     268        // Flip the lower 8 bits of v2 which is ($v[4], $v[5]) in our implementation
     269        # v2 ^= 0xff;
     270        $v[5] ^= 0xff;
     271
     272        # SIPROUND;
     273        # SIPROUND;
     274        # SIPROUND;
     275        # SIPROUND;
     276        $v = self::sipRound($v);
     277        $v = self::sipRound($v);
     278        $v = self::sipRound($v);
     279        $v = self::sipRound($v);
     280
     281        # b = v0 ^ v1 ^ v2 ^ v3;
     282        # STORE64_LE( out, b );
     283        return  self::store32_le($v[1] ^ $v[3] ^ $v[5] ^ $v[7]) .
     284            self::store32_le($v[0] ^ $v[2] ^ $v[4] ^ $v[6]);
     285    }
     286}
  • wp-includes/compat.php

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
    435435        require ABSPATH . WPINC . '/random_compat/random.php';
    436436}
    437437
     438// libsodium - modern cryptography
     439if ( ! extension_loaded( 'libsodium' ) ) {
     440    require ABSPATH . WPINC . '/sodium_compat/autoload.php';
     441}
     442
    438443if ( ! function_exists( 'array_replace_recursive' ) ) :
    439444        /**
    440445         * PHP-agnostic version of {@link array_replace_recursive()}.
  • wp-includes/sodium_compat/src/Crypto.php

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
     1<?php
     2
     3/**
     4 * Class ParagonIE_Sodium_Crypto
     5 *
     6 * ATTENTION!
     7 *
     8 * If you are using this library, you should be using
     9 * ParagonIE_Sodium_Compat in your code, not this class.
     10 */
     11abstract class ParagonIE_Sodium_Crypto
     12{
     13    const box_curve25519xsalsa20poly1305_SEEDBYTES = 32;
     14    const box_curve25519xsalsa20poly1305_PUBLICKEYBYTES = 32;
     15    const box_curve25519xsalsa20poly1305_SECRETKEYBYTES = 32;
     16    const box_curve25519xsalsa20poly1305_BEFORENMBYTES = 32;
     17    const box_curve25519xsalsa20poly1305_NONCEBYTES = 24;
     18    const box_curve25519xsalsa20poly1305_MACBYTES = 16;
     19    const box_curve25519xsalsa20poly1305_BOXZEROBYTES = 16;
     20    const box_curve25519xsalsa20poly1305_ZEROBYTES = 32;
     21
     22    const onetimeauth_poly1305_BYTES = 16;
     23    const onetimeauth_poly1305_KEYBYTES = 32;
     24
     25    const secretbox_xsalsa20poly1305_KEYBYTES = 32;
     26    const secretbox_xsalsa20poly1305_NONCEBYTES = 24;
     27    const secretbox_xsalsa20poly1305_MACBYTES = 16;
     28    const secretbox_xsalsa20poly1305_BOXZEROBYTES = 16;
     29    const secretbox_xsalsa20poly1305_ZEROBYTES = 32;
     30
     31    const stream_salsa20_KEYBYTES = 32;
     32
     33    /**
     34     * HMAC-SHA-512-256 (a.k.a. the leftmost 256 bits of HMAC-SHA-512)
     35     *
     36     * @param string $message
     37     * @param string $key
     38     * @return string
     39     */
     40    public static function auth($message, $key)
     41    {
     42        return ParagonIE_Sodium_Core_Util::substr(
     43            hash_hmac('sha512', $message, $key, true),
     44            0,
     45            32
     46        );
     47    }
     48
     49    /**
     50     * HMAC-SHA-512-256 validation. Constant-time via hash_equals().
     51     *
     52     * @param string $mac
     53     * @param string $message
     54     * @param string $key
     55     * @return bool
     56     */
     57    public static function auth_verify($mac, $message, $key)
     58    {
     59        return hash_equals(
     60            $mac,
     61            self::auth($message, $key)
     62        );
     63    }
     64
     65    /**
     66     * X25519 key exchange followed by Xsalsa20Poly1305 symmetric encryption
     67     *
     68     * @param string $plaintext
     69     * @param string $nonce
     70     * @param string $keypair
     71     * @return string
     72     */
     73    public static function box($plaintext, $nonce, $keypair)
     74    {
     75        $k = self::box_beforenm(
     76            self::box_secretkey($keypair),
     77            self::box_publickey($keypair)
     78        );
     79        $c = self::secretbox($plaintext, $nonce, $k);
     80        ParagonIE_Sodium_Compat::memzero($k);
     81        return $c;
     82    }
     83
     84    /**
     85     * X25519-Xsalsa20-Poly1305 with one ephemeral X25519 keypair.
     86     *
     87     * @param string $message
     88     * @param string $publicKey
     89     * @return string
     90     */
     91    public static function box_seal($message, $publicKey)
     92    {
     93        $ephemeralKeypair = self::box_keypair();
     94        $ephemeralSK = self::box_secretkey($ephemeralKeypair);
     95        $ephemeralPK = self::box_publickey($ephemeralKeypair);
     96
     97        $nonce = self::generichash(
     98            $ephemeralPK . $publicKey,
     99            '',
     100            24
     101        );
     102        $keypair = self::box_keypair_from_secretkey_and_publickey($ephemeralSK, $publicKey);
     103
     104        $c = self::box($message, $nonce, $keypair);
     105        ParagonIE_Sodium_Compat::memzero($ephemeralSK);
     106        ParagonIE_Sodium_Compat::memzero($nonce);
     107        return $ephemeralPK . $c;
     108    }
     109
     110    /**
     111     * Opens a message encrypted via box_seal().
     112     *
     113     * @param string $message
     114     * @param string $keypair
     115     * @return string
     116     */
     117    public static function box_seal_open($message, $keypair)
     118    {
     119        $ephemeralPK = ParagonIE_Sodium_Core_Util::substr($message, 0, 32);
     120        $c = ParagonIE_Sodium_Core_Util::substr($message, 32);
     121
     122        $secretKey = self::box_secretkey($keypair);
     123        $publicKey = self::box_publickey($keypair);
     124
     125        $nonce = self::generichash(
     126            $ephemeralPK . $publicKey,
     127            '',
     128            24
     129        );
     130        $keypair = self::box_keypair_from_secretkey_and_publickey($secretKey, $ephemeralPK);
     131        $m = self::box_open($c, $nonce, $keypair);
     132        ParagonIE_Sodium_Compat::memzero($secretKey);
     133        ParagonIE_Sodium_Compat::memzero($ephemeralPK);
     134        ParagonIE_Sodium_Compat::memzero($nonce);
     135        return $m;
     136    }
     137
     138    /**
     139     * Used by crypto_box() to get the crypto_secretbox() key.
     140     *
     141     * @param string $sk
     142     * @param string $pk
     143     * @return string
     144     */
     145    public static function box_beforenm($sk, $pk)
     146    {
     147        $s = self::scalarmult($sk, $pk);
     148        return ParagonIE_Sodium_Core_HSalsa20::hsalsa20(
     149            str_repeat("\x00", 16),
     150            $s
     151        );
     152    }
     153
     154    /**
     155     * @return string
     156     */
     157    public static function box_keypair()
     158    {
     159        $sk = random_bytes(32);
     160        $pk = self::scalarmult_base($sk);
     161        return $sk . $pk;
     162    }
     163
     164    /**
     165     * @param string $sk
     166     * @param string $pk
     167     * @return string
     168     */
     169    public static function box_keypair_from_secretkey_and_publickey($sk, $pk)
     170    {
     171        return ParagonIE_Sodium_Core_Util::substr($sk, 0, 32) .
     172            ParagonIE_Sodium_Core_Util::substr($pk, 0, 32);
     173    }
     174
     175    /**
     176     * @param string $keypair
     177     * @return string
     178     */
     179    public static function box_secretkey($keypair)
     180    {
     181        if (ParagonIE_Sodium_Core_Util::strlen($keypair) !== 64) {
     182            throw new RangeException('Must be a keypair.');
     183        }
     184        return ParagonIE_Sodium_Core_Util::substr($keypair, 0, 32);
     185    }
     186
     187    /**
     188     * @param string $keypair
     189     * @return string
     190     */
     191    public static function box_publickey($keypair)
     192    {
     193        if (ParagonIE_Sodium_Core_Util::strlen($keypair) !== 64) {
     194            throw new RangeException('Must be a keypair.');
     195        }
     196        return ParagonIE_Sodium_Core_Util::substr($keypair, 32, 32);
     197    }
     198
     199    /**
     200     * @param $sk
     201     * @return string
     202     * @throws RangeException
     203     */
     204    public static function box_publickey_from_secretkey($sk)
     205    {
     206        if (ParagonIE_Sodium_Core_Util::strlen($sk) !== 32) {
     207            throw new RangeException('Must be 32 bytes long.');
     208        }
     209        return self::scalarmult_base($sk);
     210    }
     211
     212    /**
     213     * Decrypt a message encrypted with box().
     214     *
     215     * @param string $ciphertext
     216     * @param string $nonce
     217     * @param string $nonce
     218     * @param string $keypair
     219     * @return string
     220     */
     221    public static function box_open($ciphertext, $nonce, $keypair)
     222    {
     223        $k = self::box_beforenm(
     224            self::box_secretkey($keypair),
     225            self::box_publickey($keypair)
     226        );
     227        $p = self::secretbox_open($ciphertext, $nonce, $k);
     228        ParagonIE_Sodium_Compat::memzero($k);
     229        return $p;
     230    }
     231
     232    /**
     233     * Calculate a BLAKE2b hash.
     234     *
     235     * @param string $message
     236     * @param string|null $key
     237     * @param int $outlen
     238     * @return string
     239     * @throws Exception
     240     */
     241    public static function generichash($message, $key = '', $outlen = 32)
     242    {
     243        ParagonIE_Sodium_Core_BLAKE2b::pseudoConstructor();
     244
     245        $k = null;
     246        if (!empty($key)) {
     247            $k = ParagonIE_Sodium_Core_BLAKE2b::stringToSplFixedArray($key);
     248            if ($k->count() > ParagonIE_Sodium_Core_BLAKE2b::KEYBYTES) {
     249                throw new Exception('Invalid key size');
     250            }
     251        }
     252
     253        $in = ParagonIE_Sodium_Core_BLAKE2b::stringToSplFixedArray($message);
     254        $ctx = ParagonIE_Sodium_Core_BLAKE2b::init($k, $outlen);
     255        ParagonIE_Sodium_Core_BLAKE2b::update($ctx, $in, $in->count());
     256        $out = new SplFixedArray($outlen);
     257        $out = ParagonIE_Sodium_Core_BLAKE2b::finish($ctx, $out);
     258        return ParagonIE_Sodium_Core_Util::intArrayToString($out->toArray());
     259    }
     260
     261    /**
     262     * Finalize a BLAKE2b hashing context, returning the hash.
     263     *
     264     * @param string $ctx
     265     * @param int $outlen
     266     * @return string
     267     */
     268    public static function generichash_final($ctx, $outlen = 32)
     269    {
     270        if (!is_string($ctx)) {
     271            throw new InvalidArgumentException('Context must be a string');
     272        }
     273        $out = new SplFixedArray($outlen);
     274        $context = ParagonIE_Sodium_Core_BLAKE2b::stringToContext($ctx);
     275        $out = ParagonIE_Sodium_Core_BLAKE2b::finish($context, $out);
     276        return ParagonIE_Sodium_Core_Util::intArrayToString($out->toArray());
     277    }
     278
     279    /**
     280     * Initialize a hashing context for BLAKE2b.
     281     *
     282     * @param string $key
     283     * @param int $outputLength
     284     * @return string
     285     * @throws Exception
     286     */
     287    public static function generichash_init($key = '', $outputLength = 32)
     288    {
     289        ParagonIE_Sodium_Core_BLAKE2b::pseudoConstructor();
     290
     291        $k = null;
     292        if (!empty($key)) {
     293            $k = ParagonIE_Sodium_Core_BLAKE2b::stringToSplFixedArray($key);
     294            if ($k->count() > ParagonIE_Sodium_Core_BLAKE2b::KEYBYTES) {
     295                throw new Exception('Invalid key size');
     296            }
     297        }
     298
     299        $ctx = ParagonIE_Sodium_Core_BLAKE2b::init($k, $outputLength);
     300        return ParagonIE_Sodium_Core_BLAKE2b::contextToString($ctx);
     301    }
     302
     303    /**
     304     * Update a hashing context for BLAKE2b with $message
     305     *
     306     * @param string $ctx
     307     * @param string $message
     308     * @return string
     309     */
     310    public static function generichash_update($ctx, $message)
     311    {
     312        ParagonIE_Sodium_Core_BLAKE2b::pseudoConstructor();
     313        $in = ParagonIE_Sodium_Core_BLAKE2b::stringToSplFixedArray($message);
     314        $context = ParagonIE_Sodium_Core_BLAKE2b::stringToContext($ctx);
     315        ParagonIE_Sodium_Core_BLAKE2b::update($context, $in, $in->count());
     316        return ParagonIE_Sodium_Core_BLAKE2b::contextToString($context);
     317    }
     318
     319    /**
     320     * Libsodium's crypto_kx().
     321     *
     322     * @param string $my_sk
     323     * @param string $their_pk
     324     * @param string $client_pk
     325     * @param string $server_pk
     326     * @return string
     327     */
     328    public static function kx($my_sk, $their_pk, $client_pk, $server_pk)
     329    {
     330        return self::generichash(
     331            self::scalarmult($my_sk, $their_pk) .
     332            $client_pk .
     333            $server_pk
     334        );
     335    }
     336
     337    /**
     338     * ECDH over Curve25519
     339     *
     340     * @param string $sk
     341     * @param string $pk
     342     * @return string
     343     */
     344    public static function scalarmult($sk, $pk)
     345    {
     346        return ParagonIE_Sodium_Core_X25519::crypto_scalarmult_curve25519_ref10($sk, $pk);
     347    }
     348
     349    /**
     350     * ECDH over Curve25519, using the basepoint.
     351     * Used to get a secret key from a public key.
     352     *
     353     * @param string $n
     354     * @return string
     355     */
     356    public static function scalarmult_base($n)
     357    {
     358        return ParagonIE_Sodium_Core_X25519::crypto_scalarmult_curve25519_ref10_base($n);
     359    }
     360
     361    /**
     362     * Xsalsa20-Poly1305 authenticated symmetric-key encryption.
     363     *
     364     * @param string $plaintext
     365     * @param string $nonce
     366     * @param string $key
     367     * @return string
     368     */
     369    public static function secretbox($plaintext, $nonce, $key)
     370    {
     371        $subkey = ParagonIE_Sodium_Core_HSalsa20::hsalsa20($nonce, $key);
     372
     373        $block0 = str_repeat("\x00", 32);
     374        $mlen = ParagonIE_Sodium_Core_Util::strlen($plaintext);
     375        $mlen0 = $mlen;
     376        if ($mlen0 > 64 - self::secretbox_xsalsa20poly1305_ZEROBYTES) {
     377            $mlen0 = 64 - self::secretbox_xsalsa20poly1305_ZEROBYTES;
     378        }
     379        $block0 .= ParagonIE_Sodium_Core_Util::substr($plaintext, 0, $mlen0);
     380        $block0 = ParagonIE_Sodium_Core_Salsa20::salsa20_xor(
     381            $block0,
     382            ParagonIE_Sodium_Core_Util::substr($nonce, 16, 8),
     383            $subkey
     384        );
     385        $state = new ParagonIE_Sodium_Core_Poly1305_State(
     386            ParagonIE_Sodium_Core_Util::substr(
     387                $block0,
     388                0,
     389                self::onetimeauth_poly1305_KEYBYTES
     390            )
     391        );
     392
     393        $c = ParagonIE_Sodium_Core_Util::substr(
     394            $block0,
     395            self::secretbox_xsalsa20poly1305_ZEROBYTES
     396        );
     397        if ($mlen > $mlen0) {
     398            $c .= ParagonIE_Sodium_Core_Salsa20::salsa20_xor_ic(
     399                ParagonIE_Sodium_Core_Util::substr(
     400                    $plaintext,
     401                    self::secretbox_xsalsa20poly1305_ZEROBYTES
     402                ),
     403                ParagonIE_Sodium_Core_Util::substr($nonce, 16, 8),
     404                1,
     405                $subkey
     406            );
     407        }
     408        ParagonIE_Sodium_Compat::memzero($block0);
     409        ParagonIE_Sodium_Compat::memzero($subkey);
     410
     411        $state->update($c);
     412        $c = $state->finish() . $c;
     413        unset($state);
     414
     415        return $c;
     416    }
     417
     418    /**
     419     * Decrypt a ciphertext generated via secretbox().
     420     *
     421     * @param string $ciphertext
     422     * @param string $nonce
     423     * @param string $key
     424     * @return string
     425     * @throws Exception
     426     */
     427    public static function secretbox_open($ciphertext, $nonce, $key)
     428    {
     429        $mac = ParagonIE_Sodium_Core_Util::substr(
     430            $ciphertext,
     431            0,
     432            self::box_curve25519xsalsa20poly1305_MACBYTES
     433        );
     434        $c = ParagonIE_Sodium_Core_Util::substr(
     435            $ciphertext,
     436            self::box_curve25519xsalsa20poly1305_MACBYTES
     437        );
     438        $clen = ParagonIE_Sodium_Core_Util::strlen($c);
     439
     440        $subkey = ParagonIE_Sodium_Core_HSalsa20::hsalsa20($nonce, $key);
     441        $block0 = ParagonIE_Sodium_Core_Salsa20::salsa20(
     442            64,
     443            ParagonIE_Sodium_Core_Util::substr($nonce, 16, 8),
     444            $subkey
     445        );
     446        if (!ParagonIE_Sodium_Core_Poly1305::onetimeauth_verify($mac, $c, $block0)) {
     447            ParagonIE_Sodium_Compat::memzero($subkey);
     448            throw new Exception('Invalid MAC');
     449        }
     450
     451        $m = ParagonIE_Sodium_Core_Util::xorStrings(
     452            ParagonIE_Sodium_Core_Util::substr($block0, self::secretbox_xsalsa20poly1305_ZEROBYTES),
     453            ParagonIE_Sodium_Core_Util::substr($c, 0, self::secretbox_xsalsa20poly1305_ZEROBYTES)
     454        );
     455        if ($clen > self::secretbox_xsalsa20poly1305_ZEROBYTES) {
     456            $m .= ParagonIE_Sodium_Core_Salsa20::salsa20_xor_ic(
     457                ParagonIE_Sodium_Core_Util::substr(
     458                    $c,
     459                    self::secretbox_xsalsa20poly1305_ZEROBYTES
     460                ),
     461                ParagonIE_Sodium_Core_Util::substr($nonce, 16, 8),
     462                1,
     463                $subkey
     464            );
     465        }
     466        return $m;
     467    }
     468
     469    /**
     470     * Detached Ed25519 signature.
     471     *
     472     * @param string $message
     473     * @param string $sk
     474     * @return string
     475     */
     476    public static function sign_detached($message, $sk)
     477    {
     478        return ParagonIE_Sodium_Core_Ed25519::sign_detached($message, $sk);
     479    }
     480
     481    /**
     482     * Attached Ed25519 signature. (Returns a signed message.)
     483     *
     484     * @param string $message
     485     * @param string $sk
     486     * @return string
     487     */
     488    public static function sign($message, $sk)
     489    {
     490        return ParagonIE_Sodium_Core_Ed25519::sign($message, $sk);
     491    }
     492
     493    /**
     494     * Opens a signed message. If valid, returns the message.
     495     *
     496     * @param string $signedMessage
     497     * @param string $pk
     498     * @return string
     499     */
     500    public static function sign_open($signedMessage, $pk)
     501    {
     502        return ParagonIE_Sodium_Core_Ed25519::sign_open($signedMessage, $pk);
     503    }
     504
     505    /**
     506     * Verify a detached signature of a given message and public key.
     507     *
     508     * @param string $signature
     509     * @param string $message
     510     * @param string $pk
     511     * @return bool
     512     */
     513    public static function sign_verify_detached($signature, $message, $pk)
     514    {
     515        return ParagonIE_Sodium_Core_Ed25519::verify_detached($signature, $message, $pk);
     516    }
     517}
  • wp-includes/sodium_compat/src/Compat.php

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
     1<?php
     2
     3/**
     4 * Libsodium compatibility layer
     5 */
     6class ParagonIE_Sodium_Compat
     7{
     8    /**
     9     * @var bool
     10     */
     11    public static $disableFallbackForUnitTests = false;
     12
     13    const LIBRARY_VERSION_MAJOR = 9;
     14    const LIBRARY_VERSION_MINOR = 1;
     15    const VERSION_STRING = 'polyfill-1.0.8';
     16
     17    // From libsodium
     18    const CRYPTO_AUTH_BYTES = 32;
     19    const CRYPTO_AUTH_KEYBYTES = 32;
     20    const CRYPTO_BOX_SEALBYTES = 16;
     21    const CRYPTO_BOX_SECRETKEYBYTES = 32;
     22    const CRYPTO_BOX_PUBLICKEYBYTES = 32;
     23    const CRYPTO_BOX_KEYPAIRBYTES = 64;
     24    const CRYPTO_BOX_MACBYTES = 16;
     25    const CRYPTO_BOX_NONCEBYTES = 24;
     26    const CRYPTO_BOX_SEEDBYTES = 32;
     27    const CRYPTO_KX_BYTES = 32;
     28    const CRYPTO_KX_PUBLICKEYBYTES = 32;
     29    const CRYPTO_KX_SECRETKEYBYTES = 32;
     30    const CRYPTO_GENERICHASH_BYTES = 32;
     31    const CRYPTO_GENERICHASH_BYTES_MIN = 16;
     32    const CRYPTO_GENERICHASH_BYTES_MAX = 64;
     33    const CRYPTO_GENERICHASH_KEYBYTES = 32;
     34    const CRYPTO_GENERICHASH_KEYBYTES_MIN = 16;
     35    const CRYPTO_GENERICHASH_KEYBYTES_MAX = 64;
     36    const CRYPTO_SCALARMULT_BYTES = 32;
     37    const CRYPTO_SCALARMULT_SCALARBYTES = 32;
     38    const CRYPTO_SHORTHASH_BYTES = 8;
     39    const CRYPTO_SHORTHASH_KEYBYTES = 16;
     40    const CRYPTO_SECRETBOX_KEYBYTES = 32;
     41    const CRYPTO_SECRETBOX_MACBYTES = 16;
     42    const CRYPTO_SECRETBOX_NONCEBYTES = 24;
     43    const CRYPTO_SIGN_BYTES = 64;
     44    const CRYPTO_SIGN_SEEDBYTES = 32;
     45    const CRYPTO_SIGN_PUBLICKEYBYTES = 32;
     46    const CRYPTO_SIGN_SECRETKEYBYTES = 64;
     47    const CRYPTO_SIGN_KEYPAIRBYTES = 96;
     48    const CRYPTO_STREAM_KEYBYTES = 32;
     49    const CRYPTO_STREAM_NONCEBYTES = 24;
     50
     51    /**
     52     * Cache-timing-safe implementation of bin2hex().
     53     *
     54     * @param $string
     55     * @return string
     56     * @throws TypeError
     57     */
     58    public static function bin2hex($string)
     59    {
     60        if (!is_string($string)) {
     61            throw new TypeError('Argument 1 must be a string');
     62        }
     63        if (self::use_fallback('bin2hex')) {
     64            return call_user_func_array(
     65                '\\Sodium\\bin2hex',
     66                array($string)
     67            );
     68        }
     69        return ParagonIE_Sodium_Core_Util::bin2hex($string);
     70    }
     71
     72    /**
     73     * Compare two strings, in constant-time.
     74     *
     75     * @param string $left
     76     * @param string $right
     77     * @return int
     78     * @throws TypeError
     79     */
     80    public static function compare($left, $right)
     81    {
     82        if (!is_string($left)) {
     83            throw new TypeError('Argument 1 must be a string');
     84        }
     85        if (!is_string($right)) {
     86            throw new TypeError('Argument 2 must be a string');
     87        }
     88        if (self::use_fallback('compare')) {
     89            return call_user_func_array(
     90                '\\Sodium\\compare',
     91                array($left, $right)
     92            );
     93        }
     94        return ParagonIE_Sodium_Core_Util::compare($left, $right);
     95    }
     96
     97    /**
     98     * Authenticate a message. Uses symmetric-key cryptography.
     99     *
     100     * Algorithm:
     101     *     HMAC-SHA512-256. Which is HMAC-SHA-512 truncated to 256 bits.
     102     *     Not to be confused with HMAC-SHA-512/256 which would use the
     103     *     SHA-512/256 hash function (uses different initial parameters
     104     *     but still truncates to 256 bits to sidestep length-extension
     105     *     attacks.
     106     *
     107     * @param string $message
     108     * @param string $key
     109     * @return string
     110     * @throws Error
     111     * @throws TypeError
     112     */
     113    public static function crypto_auth($message, $key)
     114    {
     115        if (!is_string($message)) {
     116            throw new TypeError('Argument 1 must be a string');
     117        }
     118        if (!is_string($key)) {
     119            throw new TypeError('Argument 2 must be a string');
     120        }
     121        if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_AUTH_KEYBYTES) {
     122            throw new Error('Argument 2 must be CRYPTO_AUTH_KEYBYTES long.');
     123        }
     124        if (self::use_fallback('crypto_auth')) {
     125            return call_user_func_array(
     126                '\\Sodium\\crypto_auth',
     127                array($message, $key)
     128            );
     129        }
     130        return ParagonIE_Sodium_Crypto::auth($message, $key);
     131    }
     132
     133    /**
     134     * Verify the MAC of a message previously authenticated with crypto_auth.
     135     *
     136     * @param string $mac
     137     * @param string $message
     138     * @param string $key
     139     * @return bool
     140     * @throws Error
     141     * @throws TypeError
     142     */
     143    public static function crypto_auth_verify($mac, $message, $key)
     144    {
     145        if (!is_string($message)) {
     146            throw new TypeError('Argument 2 must be a string');
     147        }
     148        if (!is_string($key)) {
     149            throw new TypeError('Argument 3 must be a string');
     150        }
     151        if (ParagonIE_Sodium_Core_Util::strlen($mac) !== self::CRYPTO_AUTH_BYTES) {
     152            throw new Error('Argument 1 must be CRYPTO_AUTH_BYTES long.');
     153        }
     154        if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_AUTH_KEYBYTES) {
     155            throw new Error('Argument 3 must be CRYPTO_AUTH_KEYBYTES long.');
     156        }
     157        if (self::use_fallback('crypto_auth_verify')) {
     158            return call_user_func_array(
     159                '\\Sodium\\crypto_auth_verify',
     160                array($mac, $message, $key)
     161            );
     162        }
     163        return ParagonIE_Sodium_Crypto::auth_verify($mac, $message, $key);
     164    }
     165
     166    /**
     167     * Authenticated asymmetric-key encryption. Both the sender and recipient
     168     * may decrypt messages.
     169     *
     170     * Algorithm: X25519-Xsalsa20-Poly1305.
     171     *     X25519: Elliptic-Curve Diffie Hellman over Curve25519.
     172     *     Xsalsa20: Extended-nonce variant of salsa20.
     173     *     Poyl1305: Polynomial MAC for one-time message authentication.
     174     *
     175     * @param string $plaintext
     176     * @param string $nonce
     177     * @param string $keypair
     178     * @return string
     179     * @throws Error
     180     * @throws TypeError
     181     */
     182    public static function crypto_box($plaintext, $nonce, $keypair)
     183    {
     184        if (!is_string($plaintext)) {
     185            throw new TypeError('Argument 1 must be a string');
     186        }
     187        if (!is_string($nonce)) {
     188            throw new TypeError('Argument 2 must be a string');
     189        }
     190        if (!is_string($keypair)) {
     191            throw new TypeError('Argument 3 must be a string');
     192        }
     193        if (ParagonIE_Sodium_Core_Util::strlen($nonce) !== self::CRYPTO_BOX_NONCEBYTES) {
     194            throw new Error('Argument 2 must be CRYPTO_BOX_NONCEBYTES long.');
     195        }
     196        if (ParagonIE_Sodium_Core_Util::strlen($keypair) !== self::CRYPTO_BOX_KEYPAIRBYTES) {
     197            throw new Error('Argument 3 must be CRYPTO_BOX_KEYPAIRBYTES long.');
     198        }
     199        if (self::use_fallback('crypto_box')) {
     200            return call_user_func_array(
     201                '\\Sodium\\crypto_box',
     202                array($plaintext, $nonce, $keypair)
     203            );
     204        }
     205        return ParagonIE_Sodium_Crypto::box($plaintext, $nonce, $keypair);
     206    }
     207
     208    /**
     209     * Anonymous public-key encryption. Only the recipient may decrypt messages.
     210     *
     211     * Algorithm: X25519-Xsalsa20-Poly1305, as with crypto_box.
     212     *     The sender's X25519 keypair is ephemeral.
     213     *     Nonce is generated from the BLAKE2b hash of both public keys.
     214     *
     215     * This provides ciphertext integrity.
     216     *
     217     * @param string $plaintext
     218     * @param string $publicKey
     219     * @return string
     220     * @throws Error
     221     * @throws TypeError
     222     */
     223    public static function crypto_box_seal($plaintext, $publicKey)
     224    {
     225        if (!is_string($plaintext)) {
     226            throw new TypeError('Argument 1 must be a string');
     227        }
     228        if (!is_string($publicKey)) {
     229            throw new TypeError('Argument 2 must be a string');
     230        }
     231        if (ParagonIE_Sodium_Core_Util::strlen($publicKey) !== self::CRYPTO_BOX_PUBLICKEYBYTES) {
     232            throw new Error('Argument 2 must be CRYPTO_BOX_PUBLICKEYBYTES long.');
     233        }
     234        if (self::use_fallback('crypto_box_seal')) {
     235            return call_user_func_array(
     236                '\\Sodium\\crypto_box_seal',
     237                array($plaintext, $publicKey)
     238            );
     239        }
     240        return ParagonIE_Sodium_Crypto::box_seal($plaintext, $publicKey);
     241    }
     242
     243    /**
     244     * Opens a message encrypted with crypto_box_seal(). Requires
     245     * the recipient's keypair (sk || pk) to decrypt successfully.
     246     *
     247     * This validates ciphertext integrity.
     248     *
     249     * @param string $ciphertext
     250     * @param string $keypair
     251     * @return string
     252     * @throws Error
     253     * @throws TypeError
     254     */
     255    public static function crypto_box_seal_open($ciphertext, $keypair)
     256    {
     257        if (!is_string($ciphertext)) {
     258            throw new TypeError('Argument 1 must be a string');
     259        }
     260        if (!is_string($keypair)) {
     261            throw new TypeError('Argument 2 must be a string');
     262        }
     263        if (ParagonIE_Sodium_Core_Util::strlen($keypair) !== self::CRYPTO_BOX_KEYPAIRBYTES) {
     264            throw new Error('Argument 2 must be CRYPTO_BOX_KEYPAIRBYTES long.');
     265        }
     266        if (self::use_fallback('crypto_box_seal_open')) {
     267            return call_user_func_array(
     268                '\\Sodium\\crypto_box_seal_open',
     269                array($ciphertext, $keypair)
     270            );
     271        }
     272        return ParagonIE_Sodium_Crypto::box_seal_open($ciphertext, $keypair);
     273    }
     274
     275    /**
     276     * Generate a new random X25519 keypair.
     277     *
     278     * @return string
     279     */
     280    public static function crypto_box_keypair()
     281    {
     282        if (self::use_fallback('crypto_sign_keypair')) {
     283            return call_user_func(
     284                '\\Sodium\\crypto_box_keypair'
     285            );
     286        }
     287        return ParagonIE_Sodium_Crypto::box_keypair();
     288    }
     289
     290    /**
     291     * Combine two keys into a keypair for use in library methods that expect
     292     * a keypair. This doesn't necessarily have to be the same person's keys.
     293     *
     294     * @param string $sk Secret key
     295     * @param string $pk Public key
     296     * @return string
     297     * @throws Error
     298     * @throws TypeError
     299     */
     300    public static function crypto_box_keypair_from_secretkey_and_publickey($sk, $pk)
     301    {
     302        if (!is_string($sk)) {
     303            throw new TypeError('Argument 1 must be a string');
     304        }
     305        if (ParagonIE_Sodium_Core_Util::strlen($sk) !== self::CRYPTO_BOX_SECRETKEYBYTES) {
     306            throw new Error('Argument 1 must be CRYPTO_BOX_SECRETKEYBYTES long.');
     307        }
     308        if (!is_string($pk)) {
     309            throw new TypeError('Argument 2 must be a string');
     310        }
     311        if (ParagonIE_Sodium_Core_Util::strlen($pk) !== self::CRYPTO_BOX_PUBLICKEYBYTES) {
     312            throw new Error('Argument 2 must be CRYPTO_BOX_PUBLICKEYBYTES long.');
     313        }
     314        if (self::use_fallback('box_keypair_from_secretkey_and_publickey')) {
     315            return call_user_func_array(
     316                '\\Sodium\\box_keypair_from_secretkey_and_publickey',
     317                array($sk, $pk)
     318            );
     319        }
     320        return ParagonIE_Sodium_Crypto::box_keypair_from_secretkey_and_publickey($sk, $pk);
     321    }
     322
     323    /**
     324     * Extract the public key from a crypto_box keypair.
     325     *
     326     * @param string $keypair
     327     * @return string
     328     * @throws Error
     329     * @throws TypeError
     330     */
     331    public static function crypto_box_publickey($keypair)
     332    {
     333        if (!is_string($keypair)) {
     334            throw new TypeError('Argument 1 must be a string');
     335        }
     336        if (ParagonIE_Sodium_Core_Util::strlen($keypair) !== self::CRYPTO_BOX_KEYPAIRBYTES) {
     337            throw new Error('Argument 1 must be CRYPTO_BOX_KEYPAIRBYTES long.');
     338        }
     339        if (self::use_fallback('crypto_box_publickey')) {
     340            return call_user_func_array(
     341                '\\Sodium\\crypto_box_publickey',
     342                array($keypair)
     343            );
     344        }
     345        return ParagonIE_Sodium_Crypto::box_publickey($keypair);
     346    }
     347
     348    /**
     349     * Calculate the X25519 public key from a given X25519 secret key.
     350     *
     351     * @param string $sk
     352     * @return string
     353     * @throws Error
     354     * @throws TypeError
     355     */
     356    public static function crypto_box_publickey_from_secretkey($sk)
     357    {
     358        if (!is_string($sk)) {
     359            throw new TypeError('Argument 1 must be a string');
     360        }
     361        if (ParagonIE_Sodium_Core_Util::strlen($sk) !== self::CRYPTO_BOX_SECRETKEYBYTES) {
     362            throw new Error('Argument 1 must be CRYPTO_BOX_SECRETKEYBYTES long.');
     363        }
     364        if (self::use_fallback('crypto_box_publickey_from_secretkey')) {
     365            return call_user_func_array(
     366                '\\Sodium\\crypto_box_publickey_from_secretkey',
     367                array($sk)
     368            );
     369        }
     370        return ParagonIE_Sodium_Crypto::box_publickey_from_secretkey($sk);
     371    }
     372
     373    /**
     374     * Extract the secret key from a crypto_box keypair.
     375     *
     376     * @param string $keypair
     377     * @return string
     378     * @throws Error
     379     * @throws TypeError
     380     */
     381    public static function crypto_box_secretkey($keypair)
     382    {
     383        if (!is_string($keypair)) {
     384            throw new TypeError('Argument 1 must be a string');
     385        }
     386        if (ParagonIE_Sodium_Core_Util::strlen($keypair) !== self::CRYPTO_BOX_KEYPAIRBYTES) {
     387            throw new Error('Argument 1 must be CRYPTO_BOX_KEYPAIRBYTES long.');
     388        }
     389        if (self::use_fallback('crypto_box_secretkey')) {
     390            return call_user_func_array(
     391                '\\Sodium\\crypto_box_secretkey',
     392                array($keypair)
     393            );
     394        }
     395        return ParagonIE_Sodium_Crypto::box_secretkey($keypair);
     396    }
     397
     398    /**
     399     * Decrypt a message previously encrypted with crypto_box().
     400     *
     401     * @param string $ciphertext
     402     * @param string $nonce
     403     * @param string $keypair
     404     * @return string
     405     * @throws Error
     406     * @throws TypeError
     407     */
     408    public static function crypto_box_open($ciphertext, $nonce, $keypair)
     409    {
     410        if (!is_string($ciphertext)) {
     411            throw new TypeError('Argument 1 must be a string');
     412        }
     413        if (!is_string($nonce)) {
     414            throw new TypeError('Argument 2 must be a string');
     415        }
     416        if (!is_string($keypair)) {
     417            throw new TypeError('Argument 3 must be a string');
     418        }
     419        if (ParagonIE_Sodium_Core_Util::strlen($ciphertext) < self::CRYPTO_BOX_MACBYTES) {
     420            throw new Error('Argument 1 must be at least CRYPTO_BOX_MACBYTES long.');
     421        }
     422        if (ParagonIE_Sodium_Core_Util::strlen($nonce) !== self::CRYPTO_BOX_NONCEBYTES) {
     423            throw new Error('Argument 2 must be CRYPTO_BOX_NONCEBYTES long.');
     424        }
     425        if (ParagonIE_Sodium_Core_Util::strlen($keypair) !== self::CRYPTO_BOX_KEYPAIRBYTES) {
     426            throw new Error('Argument 3 must be CRYPTO_BOX_KEYPAIRBYTES long.');
     427        }
     428        if (self::use_fallback('crypto_box_open')) {
     429            return call_user_func_array(
     430                '\\Sodium\\crypto_box_open',
     431                array($ciphertext, $nonce, $keypair)
     432            );
     433        }
     434        return ParagonIE_Sodium_Crypto::box_open($ciphertext, $nonce, $keypair);
     435    }
     436
     437    /**
     438     * Calculates a BLAKE2b hash, with an optional key.
     439     *
     440     * @param string $message
     441     * @param string $key
     442     * @param int $length
     443     * @return string
     444     * @throws Error
     445     * @throws TypeError
     446     */
     447    public static function crypto_generichash($message, $key = '', $length = 32)
     448    {
     449        if (!is_string($message)) {
     450            throw new TypeError('Argument 1 must be a string');
     451        }
     452        if (!is_string($key)) {
     453            throw new TypeError('Argument 2 must be a string');
     454        }
     455        if (!is_int($length)) {
     456            if (is_numeric($length)) {
     457                $length = (int) $length;
     458            } else {
     459                throw new TypeError('Argument 3 must be an integer');
     460            }
     461        }
     462        if (!empty($key)) {
     463            if (ParagonIE_Sodium_Core_Util::strlen($key) < self::CRYPTO_GENERICHASH_KEYBYTES_MIN) {
     464                throw new Error('Unsupported key size. Must be at least CRYPTO_GENERICHASH_KEYBYTES_MIN bytes long.');
     465            }
     466            if (ParagonIE_Sodium_Core_Util::strlen($key) > self::CRYPTO_GENERICHASH_KEYBYTES_MAX) {
     467                throw new Error('Unsupported key size. Must be at most CRYPTO_GENERICHASH_KEYBYTES_MAX bytes long.');
     468            }
     469        }
     470        if (self::use_fallback('crypto_generichash')) {
     471            return call_user_func_array(
     472                '\\Sodium\\crypto_generichash',
     473                array($message, $key, $length)
     474            );
     475        }
     476        return ParagonIE_Sodium_Crypto::generichash($message, $key, $length);
     477    }
     478
     479    /**
     480     * Get the final BLAKE2b hash output for a given context.
     481     *
     482     * @param string& $ctx
     483     * @param int $length
     484     * @return string
     485     * @throws Error
     486     * @throws TypeError
     487     */
     488    public static function crypto_generichash_final(&$ctx, $length = 32)
     489    {
     490        if (!is_string($ctx)) {
     491            throw new TypeError('Argument 1 must be a string');
     492        }
     493        if (!is_int($length)) {
     494            if (is_numeric($length)) {
     495                $length = (int) $length;
     496            } else {
     497                throw new TypeError('Argument 2 must be an integer');
     498            }
     499        }
     500        if (self::use_fallback('crypto_generichash_final')) {
     501            $func = '\\Sodium\\crypto_generichash_final';
     502            return $func($ctx, $length);
     503        }
     504        $result = ParagonIE_Sodium_Crypto::generichash_final($ctx, $length);
     505        self::memzero($ctx);
     506        return $result;
     507    }
     508
     509    /**
     510     * Initialize a BLAKE2b hashing context, for use in a streaming interface.
     511     *
     512     * @param string $key
     513     * @param int $length
     514     * @return string
     515     * @throws Error
     516     * @throws TypeError
     517     */
     518    public static function crypto_generichash_init($key = '', $length = 32)
     519    {
     520        if (!is_string($key)) {
     521            throw new TypeError('Argument 1 must be a string');
     522        }
     523        if (!is_int($length)) {
     524            if (is_numeric($length)) {
     525                $length = (int) $length;
     526            } else {
     527                throw new TypeError('Argument 2 must be an integer');
     528            }
     529        }
     530        if (!empty($key)) {
     531            if (ParagonIE_Sodium_Core_Util::strlen($key) < self::CRYPTO_GENERICHASH_KEYBYTES_MIN) {
     532                throw new Error('Unsupported key size. Must be at least CRYPTO_GENERICHASH_KEYBYTES_MIN bytes long.');
     533            }
     534            if (ParagonIE_Sodium_Core_Util::strlen($key) > self::CRYPTO_GENERICHASH_KEYBYTES_MAX) {
     535                throw new Error('Unsupported key size. Must be at most CRYPTO_GENERICHASH_KEYBYTES_MAX bytes long.');
     536            }
     537        }
     538        if (self::use_fallback('crypto_generichash_init')) {
     539            return call_user_func_array(
     540                '\\Sodium\\crypto_generichash_init',
     541                array($key, $length)
     542            );
     543        }
     544        return ParagonIE_Sodium_Crypto::generichash_init($key, $length);
     545    }
     546
     547    /**
     548     * Update a BLAKE2b hashing context with additional data.
     549     *
     550     * @param string& $ctx
     551     * @param string $message
     552     * @return void
     553     * @throws TypeError
     554     */
     555    public static function crypto_generichash_update(&$ctx, $message)
     556    {
     557        if (!is_string($ctx)) {
     558            throw new TypeError('Argument 1 must be a string');
     559        }
     560        if (!is_string($message)) {
     561            throw new TypeError('Argument 2 must be a string');
     562        }
     563        if (self::use_fallback('crypto_generichash_update')) {
     564            $func = '\\Sodium\\crypto_generichash_update';
     565            $func($ctx, $message);
     566            return;
     567        }
     568        $ctx = ParagonIE_Sodium_Crypto::generichash_update($ctx, $message);
     569    }
     570
     571    /**
     572     * Perform a key exchange, between a designated client and a server.
     573     *
     574     * @param string $my_secret
     575     * @param string $their_public
     576     * @param string $client_public
     577     * @param string $server_public
     578     * @return string
     579     * @throws Error
     580     * @throws TypeError
     581     */
     582    public static function crypto_kx($my_secret, $their_public, $client_public, $server_public)
     583    {
     584        if (!is_string($my_secret)) {
     585            throw new TypeError('Argument 1 must be a string');
     586        }
     587        if (ParagonIE_Sodium_Core_Util::strlen($my_secret) !== self::CRYPTO_BOX_SECRETKEYBYTES) {
     588            throw new Error('Argument 1 must be CRYPTO_BOX_SECRETKEYBYTES long.');
     589        }
     590        if (!is_string($their_public)) {
     591            throw new TypeError('Argument 2 must be a string');
     592        }
     593        if (ParagonIE_Sodium_Core_Util::strlen($their_public) !== self::CRYPTO_BOX_PUBLICKEYBYTES) {
     594            throw new Error('Argument 2 must be CRYPTO_BOX_PUBLICKEYBYTES long.');
     595        }
     596        if (!is_string($client_public)) {
     597            throw new TypeError('Argument 3 must be a string');
     598        }
     599        if (ParagonIE_Sodium_Core_Util::strlen($client_public) !== self::CRYPTO_BOX_PUBLICKEYBYTES) {
     600            throw new Error('Argument 3 must be CRYPTO_BOX_PUBLICKEYBYTES long.');
     601        }
     602        if (!is_string($server_public)) {
     603            throw new TypeError('Argument 4 must be a string');
     604        }
     605        if (ParagonIE_Sodium_Core_Util::strlen($server_public) !== self::CRYPTO_BOX_PUBLICKEYBYTES) {
     606            throw new Error('Argument 4 must be CRYPTO_BOX_PUBLICKEYBYTES long.');
     607        }
     608        if (self::use_fallback('crypto_kx')) {
     609            return call_user_func_array(
     610                '\\Sodium\\crypto_kx',
     611                func_get_args()
     612            );
     613        }
     614        return ParagonIE_Sodium_Crypto::kx(
     615            $my_secret,
     616            $their_public,
     617            $client_public,
     618            $server_public
     619        );
     620    }
     621
     622    /**
     623     * Calculate the shared secret between your secret key and your
     624     * recipient's public key.
     625     *
     626     * Algorithm: X25519 (ECDH over Curve25519)
     627     *
     628     * @param string $sk
     629     * @param string $pk
     630     * @return string
     631     * @throws Error
     632     * @throws TypeError
     633     */
     634    public static function crypto_scalarmult($sk, $pk)
     635    {
     636        if (!is_string($sk)) {
     637            throw new TypeError('Argument 1 must be a string');
     638        }
     639        if (ParagonIE_Sodium_Core_Util::strlen($sk) !== self::CRYPTO_BOX_SECRETKEYBYTES) {
     640            throw new Error('Argument 1 must be CRYPTO_BOX_SECRETKEYBYTES long.');
     641        }
     642        if (!is_string($pk)) {
     643            throw new TypeError('Argument 2 must be a string');
     644        }
     645        if (ParagonIE_Sodium_Core_Util::strlen($pk) !== self::CRYPTO_BOX_PUBLICKEYBYTES) {
     646            throw new Error('Argument 2 must be CRYPTO_BOX_PUBLICKEYBYTES long.');
     647        }
     648        if (self::use_fallback('crypto_scalarmult')) {
     649            return call_user_func_array(
     650                '\\Sodium\\crypto_scalarmult',
     651                array($sk, $pk)
     652            );
     653        }
     654        return ParagonIE_Sodium_Crypto::scalarmult($sk, $pk);
     655    }
     656
     657    /**
     658     * Calculate an X25519 public key from an X25519 secret key.
     659     *
     660     * @param $sk
     661     * @return string
     662     * @throws Error
     663     * @throws TypeError
     664     */
     665    public static function crypto_scalarmult_base($sk)
     666    {
     667        if (!is_string($sk)) {
     668            throw new TypeError('Argument 1 must be a string');
     669        }
     670        if (ParagonIE_Sodium_Core_Util::strlen($sk) !== self::CRYPTO_BOX_SECRETKEYBYTES) {
     671            throw new Error('Argument 1 must be CRYPTO_BOX_SECRETKEYBYTES long.');
     672        }
     673        if (self::use_fallback('crypto_scalarmult_base')) {
     674            return call_user_func_array(
     675                '\\Sodium\\crypto_scalarmult_base',
     676                array($sk)
     677            );
     678        }
     679        return ParagonIE_Sodium_Crypto::scalarmult_base($sk);
     680    }
     681
     682    /**
     683     * Authenticated symmetric-key encryption.
     684     *
     685     * Algorithm: Xsalsa20-Poly1305
     686     *
     687     * @param string $plaintext
     688     * @param string $nonce
     689     * @param string $key
     690     * @return string
     691     * @throws Error
     692     * @throws TypeError
     693     */
     694    public static function crypto_secretbox($plaintext, $nonce, $key)
     695    {
     696        if (!is_string($plaintext)) {
     697            throw new TypeError('Argument 1 must be a string');
     698        }
     699        if (!is_string($nonce)) {
     700            throw new TypeError('Argument 2 must be a string');
     701        }
     702        if (!is_string($key)) {
     703            throw new TypeError('Argument 3 must be a string');
     704        }
     705        if (ParagonIE_Sodium_Core_Util::strlen($nonce) !== self::CRYPTO_SECRETBOX_NONCEBYTES) {
     706            throw new Error('Argument 2 must be CRYPTO_SECRETBOX_NONCEBYTES long.');
     707        }
     708        if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_SECRETBOX_KEYBYTES) {
     709            throw new Error('Argument 3 must be CRYPTO_SECRETBOX_KEYBYTES long.');
     710        }
     711        if (self::use_fallback('crypto_secretbox')) {
     712            return call_user_func_array(
     713                '\\Sodium\\crypto_secretbox',
     714                array($plaintext, $nonce, $key)
     715            );
     716        }
     717        return ParagonIE_Sodium_Crypto::secretbox($plaintext, $nonce, $key);
     718    }
     719
     720    /**
     721     * Decrypts a message previously encrypted with crypto_secretbox().
     722     *
     723     * @param string $ciphertext
     724     * @param string $nonce
     725     * @param string $key
     726     * @return string
     727     * @throws Error
     728     * @throws TypeError
     729     */
     730    public static function crypto_secretbox_open($ciphertext, $nonce, $key)
     731    {
     732        if (!is_string($ciphertext)) {
     733            throw new TypeError('Argument 1 must be a string');
     734        }
     735        if (!is_string($nonce)) {
     736            throw new TypeError('Argument 2 must be a string');
     737        }
     738        if (!is_string($key)) {
     739            throw new TypeError('Argument 3 must be a string');
     740        }
     741        if (ParagonIE_Sodium_Core_Util::strlen($nonce) !== self::CRYPTO_SECRETBOX_NONCEBYTES) {
     742            throw new Error('Argument 2 must be CRYPTO_SECRETBOX_NONCEBYTES long.');
     743        }
     744        if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_SECRETBOX_KEYBYTES) {
     745            throw new Error('Argument 3 must be CRYPTO_SECRETBOX_KEYBYTES long.');
     746        }
     747        if (self::use_fallback('crypto_secretbox_open')) {
     748            return call_user_func_array(
     749                '\\Sodium\\crypto_secretbox_open',
     750                array($ciphertext, $nonce, $key)
     751            );
     752        }
     753        return ParagonIE_Sodium_Crypto::secretbox_open($ciphertext, $nonce, $key);
     754    }
     755
     756    /**
     757     * Calculates a SipHash-2-4 hash of a message for a given key.
     758     *
     759     * @param string $message
     760     * @param string $key
     761     * @return string
     762     * @throws Error
     763     * @throws TypeError
     764     */
     765    public static function crypto_shorthash($message, $key)
     766    {
     767        if (!is_string($message)) {
     768            throw new TypeError('Argument 1 must be a string');
     769        }
     770        if (!is_string($key)) {
     771            throw new TypeError('Argument 2 must be a string');
     772        }
     773        if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_SHORTHASH_KEYBYTES) {
     774            throw new Error('Argument 2 must be CRYPTO_SHORTHASH_KEYBYTES long.');
     775        }
     776        if (self::use_fallback('crypto_shorthash')) {
     777            return call_user_func_array(
     778                '\\Sodium\\crypto_shorthash',
     779                array($message, $key)
     780            );
     781        }
     782        return ParagonIE_Sodium_Core_SipHash::sipHash24($message, $key);
     783    }
     784
     785    /**
     786     * Expand a key and nonce into a keystream of pseudorandom bytes.
     787     *
     788     * @param int $len
     789     * @param string $nonce
     790     * @param string $key
     791     * @return string
     792     * @throws Error
     793     * @throws TypeError
     794     */
     795    public static function crypto_stream($len, $nonce, $key)
     796    {
     797        if (!is_int($len)) {
     798            if (is_numeric($len)) {
     799                $len = (int) $len;
     800            } else {
     801                throw new TypeError('Argument 1 must be an integer');
     802            }
     803        }
     804        if (!is_string($nonce)) {
     805            throw new TypeError('Argument 2 must be a string');
     806        }
     807        if (!is_string($key)) {
     808            throw new TypeError('Argument 3 must be a string');
     809        }
     810        if (ParagonIE_Sodium_Core_Util::strlen($nonce) !== self::CRYPTO_STREAM_NONCEBYTES) {
     811            throw new Error('Argument 2 must be CRYPTO_SECRETBOX_NONCEBYTES long.');
     812        }
     813        if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_STREAM_KEYBYTES) {
     814            throw new Error('Argument 3 must be CRYPTO_STREAM_KEYBYTES long.');
     815        }
     816        if (self::use_fallback('crypto_stream')) {
     817            return call_user_func_array(
     818                '\\Sodium\\crypto_stream',
     819                array($len, $nonce, $key)
     820            );
     821        }
     822        return ParagonIE_Sodium_Core_Xsalsa20::xsalsa20($len, $nonce, $key);
     823    }
     824
     825    /**
     826     * DANGER! UNAUTHENTICATED ENCRYPTION!
     827     *
     828     * Unless you are following expert advice, do not used this feature.
     829     *
     830     * Algorithm: Xsalsa20
     831     *
     832     * This DOES NOT provide ciphertext integrity.
     833     *
     834     * @param string $message
     835     * @param string $nonce
     836     * @param string $key
     837     * @return string
     838     * @throws Error
     839     * @throws TypeError
     840     */
     841    public static function crypto_stream_xor($message, $nonce, $key)
     842    {
     843        if (!is_string($message)) {
     844            throw new TypeError('Argument 1 must be a string');
     845        }
     846        if (!is_string($nonce)) {
     847            throw new TypeError('Argument 2 must be a string');
     848        }
     849        if (!is_string($key)) {
     850            throw new TypeError('Argument 3 must be a string');
     851        }
     852        if (ParagonIE_Sodium_Core_Util::strlen($nonce) !== self::CRYPTO_STREAM_NONCEBYTES) {
     853            throw new Error('Argument 2 must be CRYPTO_SECRETBOX_NONCEBYTES long.');
     854        }
     855        if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_STREAM_KEYBYTES) {
     856            throw new Error('Argument 3 must be CRYPTO_SECRETBOX_KEYBYTES long.');
     857        }
     858        if (self::use_fallback('crypto_stream_xor')) {
     859            return call_user_func_array(
     860                '\\Sodium\\crypto_stream_xor',
     861                array($message, $nonce, $key)
     862            );
     863        }
     864        return ParagonIE_Sodium_Core_Xsalsa20::xsalsa20_xor($message, $nonce, $key);
     865    }
     866
     867    /**
     868     * Returns a signed message. You probably want crypto_sign_detached()
     869     * instead, which only returns the signature.
     870     *
     871     * Algorithm: Ed25519 (EdDSA over Curve25519)
     872     *
     873     * @param string $message
     874     * @param string $sk
     875     * @return string
     876     * @throws Error
     877     * @throws TypeError
     878     */
     879    public static function crypto_sign($message, $sk)
     880    {
     881        if (!is_string($message)) {
     882            throw new TypeError('Argument 1 must be a string');
     883        }
     884        if (!is_string($sk)) {
     885            throw new TypeError('Argument 2 must be a string');
     886        }
     887        if (ParagonIE_Sodium_Core_Util::strlen($sk) !== self::CRYPTO_SIGN_SECRETKEYBYTES) {
     888            throw new Error('Argument 2 must be CRYPTO_SIGN_SECRETKEYBYTES long.');
     889        }
     890        if (self::use_fallback('crypto_sign')) {
     891            return call_user_func_array(
     892                '\\Sodium\\crypto_sign',
     893                array($message, $sk)
     894            );
     895        }
     896        return ParagonIE_Sodium_Crypto::sign($message, $sk);
     897    }
     898
     899    /**
     900     * Validates a signed message then returns the message.
     901     *
     902     * @param string $sm
     903     * @param string $pk
     904     * @return string
     905     * @throws Error
     906     * @throws TypeError
     907     */
     908    public static function crypto_sign_open($sm, $pk)
     909    {
     910        if (!is_string($sm)) {
     911            throw new TypeError('Argument 1 must be a string');
     912        }
     913        if (!is_string($pk)) {
     914            throw new TypeError('Argument 2 must be a string');
     915        }
     916        if (ParagonIE_Sodium_Core_Util::strlen($pk) !== self::CRYPTO_SIGN_PUBLICKEYBYTES) {
     917            throw new Error('Argument 2 must be CRYPTO_SIGN_PUBLICKEYBYTES long.');
     918        }
     919        if (self::use_fallback('crypto_sign_open')) {
     920            return call_user_func_array(
     921                '\\Sodium\\crypto_sign_open',
     922                array($sm, $pk)
     923            );
     924        }
     925        return ParagonIE_Sodium_Crypto::sign_open($sm, $pk);
     926    }
     927
     928    /**
     929     * Generate a new random Ed25519 keypair.
     930     *
     931     * @return string
     932     */
     933    public static function crypto_sign_keypair()
     934    {
     935        if (self::use_fallback('crypto_sign_keypair')) {
     936            return call_user_func(
     937                '\\Sodium\\crypto_sign_keypair'
     938            );
     939        }
     940        return ParagonIE_Sodium_Core_Ed25519::keypair();
     941    }
     942
     943    /**
     944     * Generate an Ed25519 keypair from a seed.
     945     *
     946     * @return string
     947     */
     948    public static function crypto_sign_seed_keypair($seed)
     949    {
     950        if (self::use_fallback('crypto_sign_keypair')) {
     951            return call_user_func_array(
     952                '\\Sodium\\crypto_sign_seed_keypair',
     953                array($seed)
     954            );
     955        }
     956        $pk = '';
     957        $sk = '';
     958        ParagonIE_Sodium_Core_Ed25519::seed_keypair($pk, $sk, $seed);
     959        return $sk . $pk;
     960    }
     961
     962    /**
     963     * Extract an Ed25519 public key from an Ed25519 keypair.
     964     *
     965     * @param string $keypair
     966     * @return string
     967     * @throws Error
     968     * @throws TypeError
     969     */
     970    public static function crypto_sign_publickey($keypair)
     971    {
     972        if (!is_string($keypair)) {
     973            throw new TypeError('Argument 1 must be a string');
     974        }
     975        if (ParagonIE_Sodium_Core_Util::strlen($keypair) !== self::CRYPTO_SIGN_KEYPAIRBYTES) {
     976            throw new Error('Argument 1 must be CRYPTO_SIGN_KEYPAIRBYTES long.');
     977        }
     978        if (self::use_fallback('crypto_sign_publickey')) {
     979            return call_user_func_array(
     980                '\\Sodium\\crypto_sign_publickey',
     981                array($keypair)
     982            );
     983        }
     984        return ParagonIE_Sodium_Core_Ed25519::publickey($keypair);
     985    }
     986    /**
     987     * Calculate an Ed25519 public key from an Ed25519 secret key.
     988     *
     989     * @param string $sk
     990     * @return string
     991     * @throws Error
     992     * @throws TypeError
     993     */
     994    public static function crypto_sign_publickey_from_secretkey($sk)
     995    {
     996        if (!is_string($sk)) {
     997            throw new TypeError('Argument 1 must be a string');
     998        }
     999        if (ParagonIE_Sodium_Core_Util::strlen($sk) !== self::CRYPTO_SIGN_SECRETKEYBYTES) {
     1000            throw new Error('Argument 1 must be CRYPTO_SIGN_SECRETKEYBYTES long.');
     1001        }
     1002        if (self::use_fallback('crypto_sign_publickey_from_publickey')) {
     1003            return call_user_func_array(
     1004                '\\Sodium\\crypto_sign_publickey_from_publickey',
     1005                array($sk)
     1006            );
     1007        }
     1008        return ParagonIE_Sodium_Core_Ed25519::publickey_from_secretkey($sk);
     1009    }
     1010
     1011    /**
     1012     * Extract an Ed25519 secret key from an Ed25519 keypair.
     1013     *
     1014     * @param string $keypair
     1015     * @return string
     1016     * @throws Error
     1017     * @throws TypeError
     1018     */
     1019    public static function crypto_sign_secretkey($keypair)
     1020    {
     1021        if (!is_string($keypair)) {
     1022            throw new TypeError('Argument 1 must be a string');
     1023        }
     1024        if (ParagonIE_Sodium_Core_Util::strlen($keypair) !== self::CRYPTO_SIGN_KEYPAIRBYTES) {
     1025            throw new Error('Argument 1 must be CRYPTO_SIGN_KEYPAIRBYTES long.');
     1026        }
     1027        if (self::use_fallback('crypto_sign_secretkey')) {
     1028            return call_user_func_array(
     1029                '\\Sodium\\crypto_sign_secretkey',
     1030                array($keypair)
     1031            );
     1032        }
     1033        return ParagonIE_Sodium_Core_Ed25519::secretkey($keypair);
     1034    }
     1035
     1036    /**
     1037     * Calculate the Ed25519 signature of a message and return ONLY the signature.
     1038     *
     1039     * Algorithm: Ed25519 (EdDSA over Curve25519)
     1040     *
     1041     * @param string $message
     1042     * @param string $sk
     1043     * @return string
     1044     * @throws Error
     1045     * @throws TypeError
     1046     */
     1047    public static function crypto_sign_detached($message, $sk)
     1048    {
     1049        if (!is_string($message)) {
     1050            throw new TypeError('Argument 1 must be a string');
     1051        }
     1052        if (!is_string($sk)) {
     1053            throw new TypeError('Argument 2 must be a string');
     1054        }
     1055        if (ParagonIE_Sodium_Core_Util::strlen($sk) !== self::CRYPTO_SIGN_SECRETKEYBYTES) {
     1056            throw new Error('Argument 2 must be CRYPTO_SIGN_SECRETKEYBYTES long.');
     1057        }
     1058        if (self::use_fallback('crypto_sign_detached')) {
     1059            return call_user_func_array(
     1060                '\\Sodium\\crypto_sign_detached',
     1061                array($message, $sk)
     1062            );
     1063        }
     1064        return ParagonIE_Sodium_Crypto::sign_detached($message, $sk);
     1065    }
     1066
     1067    /**
     1068     * Verify the signature of a message.
     1069     *
     1070     * @param string $signature
     1071     * @param string $message
     1072     * @param string $pk
     1073     * @return bool
     1074     * @throws Error
     1075     * @throws TypeError
     1076     */
     1077    public static function crypto_sign_verify_detached($signature, $message, $pk)
     1078    {
     1079        if (!is_string($signature)) {
     1080            throw new TypeError('Argument 1 must be a string');
     1081        }
     1082        if (!is_string($message)) {
     1083            throw new TypeError('Argument 2 must be a string');
     1084        }
     1085        if (!is_string($pk)) {
     1086            throw new TypeError('Argument 3 must be a string');
     1087        }
     1088        if (ParagonIE_Sodium_Core_Util::strlen($signature) !== self::CRYPTO_SIGN_BYTES) {
     1089            throw new Error('Argument 1 must be CRYPTO_SIGN_BYTES long.');
     1090        }
     1091        if (ParagonIE_Sodium_Core_Util::strlen($pk) !== self::CRYPTO_SIGN_PUBLICKEYBYTES) {
     1092            throw new Error('Argument 3 must be CRYPTO_SIGN_PUBLICKEYBYTES long.');
     1093        }
     1094        if (self::use_fallback('crypto_sign_verify_detached')) {
     1095            return call_user_func_array(
     1096                '\\Sodium\\crypto_sign_verify_detached',
     1097                array($signature, $message, $pk)
     1098            );
     1099        }
     1100        return ParagonIE_Sodium_Crypto::sign_verify_detached($signature, $message, $pk);
     1101    }
     1102
     1103    /**
     1104     * Cache-timing-safe implementation of hex2bin().
     1105     *
     1106     * @param $string
     1107     * @return string
     1108     * @throws TypeError
     1109     */
     1110    public static function hex2bin($string)
     1111    {
     1112        if (!is_string($string)) {
     1113            throw new TypeError('Argument 1 must be a string');
     1114        }
     1115        if (self::use_fallback('hex2bin')) {
     1116            return call_user_func_array(
     1117                '\\Sodium\\hex2bin',
     1118                array($string)
     1119            );
     1120        }
     1121        return ParagonIE_Sodium_Core_Util::hex2bin($string);
     1122    }
     1123
     1124    /**
     1125     * @return int
     1126     */
     1127    public static function library_version_major()
     1128    {
     1129        if (self::use_fallback('hex2bin')) {
     1130            return (int) call_user_func('\\Sodium\\library_version_minor');
     1131        }
     1132        return self::LIBRARY_VERSION_MAJOR;
     1133    }
     1134
     1135    /**
     1136     * @return int
     1137     */
     1138    public static function library_version_minor()
     1139    {
     1140        if (self::use_fallback('library_version_minor')) {
     1141            return (int) call_user_func('\\Sodium\\library_version_minor');
     1142        }
     1143        return self::LIBRARY_VERSION_MINOR;
     1144    }
     1145
     1146    /**
     1147     * Compare two strings.
     1148     *
     1149     * @param string $left
     1150     * @param string $right
     1151     * @return int
     1152     * @throws TypeError
     1153     */
     1154    public static function memcmp($left, $right)
     1155    {
     1156        if (!is_string($left)) {
     1157            throw new TypeError('Argument 1 must be a string');
     1158        }
     1159        if (!is_string($right)) {
     1160            throw new TypeError('Argument 1 must be a string');
     1161        }
     1162        if (self::use_fallback('memcmp')) {
     1163            return call_user_func_array(
     1164                '\\Sodium\\memcmp',
     1165                array($left, $right)
     1166            );
     1167        }
     1168        return ParagonIE_Sodium_Core_Util::memcmp($left, $right);
     1169    }
     1170
     1171    /**
     1172     * This is a NOP in the userland implementation. It's actually not possible
     1173     * to zero memory buffers in PHP. You need the native library for that.
     1174     *
     1175     * @param &string $var
     1176     * @throws TypeError
     1177     */
     1178    public static function memzero(&$var)
     1179    {
     1180        if (!is_string($var)) {
     1181            throw new TypeError('Argument 1 must be a string');
     1182        }
     1183        if (self::use_fallback('memzero')) {
     1184            call_user_func_array(
     1185                '\\Sodium\\memzero',
     1186                array(&$var)
     1187            );
     1188            return;
     1189        }
     1190        // This is the best we can do.
     1191        unset($var);
     1192    }
     1193
     1194    /**
     1195     * Generate a string of bytes from the kernel's CSPRNG.
     1196     * Proudly uses /dev/urandom (if getrandom(2) is not available).
     1197     *
     1198     * @param int $numBytes
     1199     * @return string
     1200     * @throws TypeError
     1201     */
     1202    public static function randombytes_buf($numBytes)
     1203    {
     1204        if (!is_int($numBytes)) {
     1205            if (is_numeric($numBytes)) {
     1206                $numBytes = (int) $numBytes;
     1207            } else {
     1208                throw new TypeError('Argument 1 must be an integer');
     1209            }
     1210        }
     1211        if (self::use_fallback('randombytes_buf')) {
     1212            return call_user_func_array(
     1213                '\\Sodium\\randombytes_buf',
     1214                array($numBytes)
     1215            );
     1216        }
     1217        return random_bytes($numBytes);
     1218    }
     1219
     1220    /**
     1221     * Generate an integer between 0 and $range (non-inclusive).
     1222     *
     1223     * @param int $range
     1224     * @return int
     1225     * @throws TypeError
     1226     */
     1227    public static function randombytes_uniform($range)
     1228    {
     1229        if (!is_int($range)) {
     1230            if (is_numeric($range)) {
     1231                $range = (int) $range;
     1232            } else {
     1233                throw new TypeError('Argument 1 must be an integer');
     1234            }
     1235        }
     1236        if (self::use_fallback('randombytes_uniform')) {
     1237            return (int) call_user_func_array(
     1238                '\\Sodium\\randombytes_uniform',
     1239                array($range)
     1240            );
     1241        }
     1242        return random_int(0, $range - 1);
     1243    }
     1244
     1245    /**
     1246     * Generate a random 16-bit integer.
     1247     *
     1248     * @return int
     1249     */
     1250    public static function randombytes_random16()
     1251    {
     1252        if (self::use_fallback('randombytes_random16')) {
     1253            return (int) call_user_func('\\Sodium\\randombytes_random16');
     1254        }
     1255        return random_int(0, 65535);
     1256    }
     1257
     1258    /**
     1259     * @return string
     1260     */
     1261    public static function version_string()
     1262    {
     1263        if (self::use_fallback('version_string')) {
     1264            return (int) call_user_func('\\Sodium\\version_string');
     1265        }
     1266        return self::VERSION_STRING;
     1267    }
     1268
     1269    /**
     1270     * Should we use the libsodium core function instead?
     1271     *
     1272     * @param string $sodium_func_name
     1273     * @return bool
     1274     */
     1275    protected static function use_fallback($sodium_func_name = '')
     1276    {
     1277        static $res = null;
     1278        if ($res === null) {
     1279            $res = extension_loaded('libsodium') && PHP_VERSION_ID >= 50300;
     1280        }
     1281        if ($res === false) {
     1282            // No libsodium installed
     1283            return false;
     1284        }
     1285        if (self::$disableFallbackForUnitTests) {
     1286            // Don't fallback. Use the PHP implementation.
     1287            return false;
     1288        }
     1289        if (!empty($sodium_func_name)) {
     1290            return is_callable('\\Sodium\\' . $sodium_func_name);
     1291        }
     1292        return true;
     1293    }
     1294}
  • wp-includes/sodium_compat/src/Core/Curve25519/Ge/Cached.php

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
     1<?php
     2
     3/**
     4 * Class ParagonIE_Sodium_Core_Curve25519_Ge_Cached
     5 */
     6class ParagonIE_Sodium_Core_Curve25519_Ge_Cached
     7{
     8    /**
     9     * @var ParagonIE_Sodium_Core_Curve25519_Fe
     10     */
     11    public $YplusX;
     12
     13    /**
     14     * @var ParagonIE_Sodium_Core_Curve25519_Fe
     15     */
     16    public $YminusX;
     17
     18    /**
     19     * @var ParagonIE_Sodium_Core_Curve25519_Fe
     20     */
     21    public $Z;
     22
     23    /**
     24     * @var ParagonIE_Sodium_Core_Curve25519_Fe
     25     */
     26    public $T2d;
     27
     28    /**
     29     * ParagonIE_Sodium_Core_Curve25519_Ge_Cached constructor.
     30     * @param ParagonIE_Sodium_Core_Curve25519_Fe|null $YplusX
     31     * @param ParagonIE_Sodium_Core_Curve25519_Fe|null $YminusX
     32     * @param ParagonIE_Sodium_Core_Curve25519_Fe|null $Z
     33     * @param ParagonIE_Sodium_Core_Curve25519_Fe|null $T2d
     34     */
     35    public function __construct(
     36        ParagonIE_Sodium_Core_Curve25519_Fe $YplusX = null,
     37        ParagonIE_Sodium_Core_Curve25519_Fe $YminusX = null,
     38        ParagonIE_Sodium_Core_Curve25519_Fe $Z = null,
     39        ParagonIE_Sodium_Core_Curve25519_Fe $T2d = null
     40    ) {
     41        $this->YplusX = $YplusX;
     42        $this->YminusX = $YminusX;
     43        $this->Z = $Z;
     44        $this->T2d = $T2d;
     45    }
     46}
     47 No newline at end of file
  • wp-includes/sodium_compat/lib/sodium_compat.php

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
     1<?php
     2namespace Sodium;
     3
     4use ParagonIE_Sodium_Compat;
     5
     6/**
     7 * This file will monkey patch the pure-PHP implementation in place of the
     8 * PECL functions, but only if they do not already exist.
     9 *
     10 * Thus, the functions just proxy to the appropriate ParagonIE_Sodium_Compat
     11 * method.
     12 */
     13if (!is_callable('\\Sodium\\bin2hex')) {
     14    /**
     15     * @param $string
     16     * @return string
     17     */
     18    function bin2hex($string)
     19    {
     20        return ParagonIE_Sodium_Compat::bin2hex($string);
     21    }
     22}
     23if (!is_callable('\\Sodium\\compare')) {
     24    /**
     25     * @param string $a
     26     * @param string $b
     27     * @return int
     28     */
     29    function compare($a, $b)
     30    {
     31        return ParagonIE_Sodium_Compat::compare($a, $b);
     32    }
     33}
     34if (!is_callable('\\Sodium\\crypto_auth')) {
     35    /**
     36     * @param string $message
     37     * @param string $key
     38     * @return string
     39     */
     40    function crypto_auth($message, $key)
     41    {
     42        return ParagonIE_Sodium_Compat::crypto_auth($message, $key);
     43    }
     44}
     45if (!is_callable('\\Sodium\\crypto_auth_verify')) {
     46    /**
     47     * @param string $mac
     48     * @param string $message
     49     * @param string $key
     50     * @return bool
     51     */
     52    function crypto_auth_verify($mac, $message, $key)
     53    {
     54        return ParagonIE_Sodium_Compat::crypto_auth_verify($mac, $message, $key);
     55    }
     56}
     57if (!is_callable('\\Sodium\\crypto_box')) {
     58    /**
     59     * @param string $message
     60     * @param string $nonce
     61     * @param string $kp
     62     * @return string
     63     */
     64    function crypto_box($message, $nonce, $kp)
     65    {
     66        return ParagonIE_Sodium_Compat::crypto_box($message, $nonce, $kp);
     67    }
     68}
     69if (!is_callable('\\Sodium\\crypto_box_keypair')) {
     70    /**
     71     * @return string
     72     */
     73    function crypto_box_keypair()
     74    {
     75        return ParagonIE_Sodium_Compat::crypto_box_keypair();
     76    }
     77}
     78if (!is_callable('\\Sodium\\crypto_box_keypair_from_secretkey_and_publickey')) {
     79    /**
     80     * @param string $sk
     81     * @param string $pk
     82     * @return string
     83     */
     84    function crypto_box_keypair_from_secretkey_and_publickey($sk, $pk)
     85    {
     86        return ParagonIE_Sodium_Compat::crypto_box_keypair_from_secretkey_and_publickey($sk, $pk);
     87    }
     88}
     89if (!is_callable('\\Sodium\\crypto_box_open')) {
     90    /**
     91     * @param string $message
     92     * @param string $nonce
     93     * @param string $kp
     94     * @return string
     95     */
     96    function crypto_box_open($message, $nonce, $kp)
     97    {
     98        return ParagonIE_Sodium_Compat::crypto_box_open($message, $nonce, $kp);
     99    }
     100}
     101if (!is_callable('\\Sodium\\crypto_box_publickey')) {
     102    /**
     103     * @param string $keypair
     104     * @return string
     105     */
     106    function crypto_box_publickey($keypair)
     107    {
     108        return ParagonIE_Sodium_Compat::crypto_box_publickey($keypair);
     109    }
     110}
     111if (!is_callable('\\Sodium\\crypto_box_publickey_from_secretkey')) {
     112    /**
     113     * @param string $sk
     114     * @return string
     115     */
     116    function crypto_box_publickey_from_secretkey($sk)
     117    {
     118        return ParagonIE_Sodium_Compat::crypto_box_publickey_from_secretkey($sk);
     119    }
     120}
     121if (!is_callable('\\Sodium\\crypto_box_seal')) {
     122    /**
     123     * @param string $message
     124     * @param string $publicKey
     125     * @return string
     126     */
     127    function crypto_box_seal($message, $publicKey)
     128    {
     129        return ParagonIE_Sodium_Compat::crypto_box_seal($message, $publicKey);
     130    }
     131}
     132if (!is_callable('\\Sodium\\crypto_box_seal_open')) {
     133    /**
     134     * @param string $message
     135     * @param string $kp
     136     * @return string
     137     */
     138    function crypto_box_seal_open($message, $kp)
     139    {
     140        return ParagonIE_Sodium_Compat::crypto_box_seal_open($message, $kp);
     141    }
     142}
     143if (!is_callable('\\Sodium\\crypto_box_secretkey')) {
     144    /**
     145     * @param string $keypair
     146     * @return string
     147     */
     148    function crypto_box_secretkey($keypair)
     149    {
     150        return ParagonIE_Sodium_Compat::crypto_box_secretkey($keypair);
     151    }
     152}
     153if (!is_callable('\\Sodium\\crypto_generichash')) {
     154    /**
     155     * @param string $message
     156     * @param string|null $key
     157     * @param int $outLen
     158     * @return string
     159     */
     160    function crypto_generichash($message, $key = null, $outLen = 32)
     161    {
     162        return ParagonIE_Sodium_Compat::crypto_generichash($message, $key, $outLen);
     163    }
     164}
     165if (!is_callable('\\Sodium\\crypto_generichash_final')) {
     166    /**
     167     * @param string|null $ctx
     168     * @param int $outputLength
     169     * @return string
     170     */
     171    function crypto_generichash_final(&$ctx, $outputLength = 32)
     172    {
     173        return ParagonIE_Sodium_Compat::crypto_generichash_final($ctx, $outputLength);
     174    }
     175}
     176if (!is_callable('\\Sodium\\crypto_generichash_init')) {
     177    /**
     178     * @param string|null $key
     179     * @param int $outLen
     180     * @return string
     181     */
     182    function crypto_generichash_init($key = null, $outLen = 32)
     183    {
     184        return ParagonIE_Sodium_Compat::crypto_generichash_init($key, $outLen);
     185    }
     186}
     187if (!is_callable('\\Sodium\\crypto_generichash_update')) {
     188    /**
     189     * @param string|null $ctx
     190     * @param string $message
     191     * @return void
     192     */
     193    function crypto_generichash_update(&$ctx, $message = '')
     194    {
     195        ParagonIE_Sodium_Compat::crypto_generichash_update($ctx, $message);
     196    }
     197}
     198if (!is_callable('\\Sodium\\crypto_kx')) {
     199    /**
     200     * @param string $my_secret
     201     * @param string $their_public
     202     * @param string $client_public
     203     * @param string $server_public
     204     * @return string
     205     */
     206    function crypto_kx($my_secret, $their_public, $client_public, $server_public)
     207    {
     208        return ParagonIE_Sodium_Compat::crypto_kx(
     209            $my_secret,
     210            $their_public,
     211            $client_public,
     212            $server_public
     213        );
     214    }
     215}
     216if (!is_callable('\\Sodium\\crypto_scalarmult')) {
     217    /**
     218     * @param string $n
     219     * @param string $p
     220     * @return string
     221     */
     222    function crypto_scalarmult($n, $p)
     223    {
     224        return ParagonIE_Sodium_Compat::crypto_scalarmult($n, $p);
     225    }
     226}
     227if (!is_callable('\\Sodium\\crypto_secretbox')) {
     228    /**
     229     * @param string $message
     230     * @param string $nonce
     231     * @param string $key
     232     * @return string
     233     */
     234    function crypto_secretbox($message, $nonce, $key)
     235    {
     236        return ParagonIE_Sodium_Compat::crypto_secretbox($message, $nonce, $key);
     237    }
     238}
     239if (!is_callable('\\Sodium\\crypto_secretbox_open')) {
     240    /**
     241     * @param string $message
     242     * @param string $nonce
     243     * @param string $key
     244     * @return string
     245     */
     246    function crypto_secretbox_open($message, $nonce, $key)
     247    {
     248        return ParagonIE_Sodium_Compat::crypto_secretbox_open($message, $nonce, $key);
     249    }
     250}
     251if (!is_callable('\\Sodium\\crypto_shorthash')) {
     252    /**
     253     * @param string $message
     254     * @param string $key
     255     * @return string
     256     */
     257    function crypto_shorthash($message, $key = '')
     258    {
     259        return ParagonIE_Sodium_Compat::crypto_shorthash($message, $key);
     260    }
     261}
     262if (!is_callable('\\Sodium\\crypto_sign')) {
     263    /**
     264     * @param string $message
     265     * @param string $sk
     266     * @return string
     267     */
     268    function crypto_sign($message, $sk)
     269    {
     270        return ParagonIE_Sodium_Compat::crypto_sign($message, $sk);
     271    }
     272}
     273if (!is_callable('\\Sodium\\crypto_sign_detached')) {
     274    /**
     275     * @param string $message
     276     * @param string $sk
     277     * @return string
     278     */
     279    function crypto_sign_detached($message, $sk)
     280    {
     281        return ParagonIE_Sodium_Compat::crypto_sign_detached($message, $sk);
     282    }
     283}
     284if (!is_callable('\\Sodium\\crypto_sign_keypair')) {
     285    /**
     286     * @return string
     287     */
     288    function crypto_sign_keypair()
     289    {
     290        return ParagonIE_Sodium_Compat::crypto_sign_keypair();
     291    }
     292}
     293if (!is_callable('\\Sodium\\crypto_sign_open')) {
     294    /**
     295     * @param string $signedMessage
     296     * @param string $pk
     297     * @return string
     298     */
     299    function crypto_sign_open($signedMessage, $pk)
     300    {
     301        return ParagonIE_Sodium_Compat::crypto_sign_open($signedMessage, $pk);
     302    }
     303}
     304if (!is_callable('\\Sodium\\crypto_sign_publickey')) {
     305    /**
     306     * @param string $keypair
     307     * @return string
     308     */
     309    function crypto_sign_publickey($keypair)
     310    {
     311        return ParagonIE_Sodium_Compat::crypto_sign_publickey($keypair);
     312    }
     313}
     314if (!is_callable('\\Sodium\\crypto_sign_publickey_from_secretkey')) {
     315    /**
     316     * @param string $sk
     317     * @return string
     318     */
     319    function crypto_sign_publickey_from_secretkey($sk)
     320    {
     321        return ParagonIE_Sodium_Compat::crypto_sign_publickey_from_secretkey($sk);
     322    }
     323}
     324if (!is_callable('\\Sodium\\crypto_sign_secretkey')) {
     325    /**
     326     * @param string $keypair
     327     * @return string
     328     */
     329    function crypto_sign_secretkey($keypair)
     330    {
     331        return ParagonIE_Sodium_Compat::crypto_sign_secretkey($keypair);
     332    }
     333}
     334if (!is_callable('\\Sodium\\crypto_sign_verify_detached')) {
     335    /**
     336     * @param string $signature
     337     * @param string $message
     338     * @param string $pk
     339     * @return bool
     340     */
     341    function crypto_sign_verify_detached($signature, $message, $pk)
     342    {
     343        return ParagonIE_Sodium_Compat::crypto_sign_verify_detached($signature, $message, $pk);
     344    }
     345}
     346if (!is_callable('\\Sodium\\crypto_stream')) {
     347    /**
     348     * @param int $len
     349     * @param string $nonce
     350     * @param string $key
     351     * @return string
     352     */
     353    function crypto_stream($len, $nonce, $key)
     354    {
     355        return ParagonIE_Sodium_Compat::crypto_stream($len, $nonce, $key);
     356    }
     357}
     358if (!is_callable('\\Sodium\\crypto_stream_xor')) {
     359    /**
     360     * @param $message
     361     * @param $nonce
     362     * @param $key
     363     * @return mixed
     364     */
     365    function crypto_stream_xor($message, $nonce, $key)
     366    {
     367        return ParagonIE_Sodium_Compat::crypto_stream_xor($message, $nonce, $key);
     368    }
     369}
     370if (!is_callable('\\Sodium\\hex2bin')) {
     371    /**
     372     * @param $string
     373     * @return string
     374     */
     375    function hex2bin($string)
     376    {
     377        return ParagonIE_Sodium_Compat::hex2bin($string);
     378    }
     379}
     380if (!is_callable('\\Sodium\\memcmp')) {
     381    /**
     382     * @param string $a
     383     * @param string $b
     384     * @return int
     385     */
     386    function memcmp($a, $b)
     387    {
     388        return ParagonIE_Sodium_Compat::memcmp($a, $b);
     389    }
     390}
     391if (!is_callable('\\Sodium\\randombytes_buf')) {
     392    /**
     393     * @param int $amount
     394     * @return string
     395     */
     396    function randombytes_buf($amount)
     397    {
     398        return ParagonIE_Sodium_Compat::randombytes_buf($amount);
     399    }
     400}
     401
     402if (!is_callable('\\Sodium\\randombytes_uniform')) {
     403    /**
     404     * @param int $upperLimit
     405     * @return int
     406     */
     407    function randombytes_uniform($upperLimit)
     408    {
     409        return ParagonIE_Sodium_Compat::randombytes_uniform($upperLimit);
     410    }
     411}
     412
     413if (!is_callable('\\Sodium\\randombytes_random16')) {
     414    /**
     415     * @return int
     416     */
     417    function randombytes_random16()
     418    {
     419        return ParagonIE_Sodium_Compat::randombytes_random16();
     420    }
     421}
     422
     423if (!defined('\\Sodium\\CRYPTO_AUTH_BYTES')) {
     424    define('\\Sodium\\CRYPTO_AUTH_BYTES', ParagonIE_Sodium_Compat::CRYPTO_AUTH_BYTES);
     425}
     426if (!defined('\\Sodium\\CRYPTO_AUTH_KEYBYTES')) {
     427    define('\\Sodium\\CRYPTO_AUTH_KEYBYTES', ParagonIE_Sodium_Compat::CRYPTO_AUTH_KEYBYTES);
     428}
     429if (!defined('\\Sodium\\CRYPTO_BOX_SEALBYTES')) {
     430    define('\\Sodium\\CRYPTO_BOX_SEALBYTES', ParagonIE_Sodium_Compat::CRYPTO_BOX_SEALBYTES);
     431}
     432if (!defined('\\Sodium\\CRYPTO_BOX_SECRETKEYBYTES')) {
     433    define('\\Sodium\\CRYPTO_BOX_SECRETKEYBYTES', ParagonIE_Sodium_Compat::CRYPTO_BOX_SECRETKEYBYTES);
     434}
     435if (!defined('\\Sodium\\CRYPTO_BOX_PUBLICKEYBYTES')) {
     436    define('\\Sodium\\CRYPTO_BOX_PUBLICKEYBYTES', ParagonIE_Sodium_Compat::CRYPTO_BOX_PUBLICKEYBYTES);
     437}
     438if (!defined('\\Sodium\\CRYPTO_BOX_KEYPAIRBYTES')) {
     439    define('\\Sodium\\CRYPTO_BOX_KEYPAIRBYTES', ParagonIE_Sodium_Compat::CRYPTO_BOX_KEYPAIRBYTES);
     440}
     441if (!defined('\\Sodium\\CRYPTO_BOX_MACBYTES')) {
     442    define('\\Sodium\\CRYPTO_BOX_MACBYTES', ParagonIE_Sodium_Compat::CRYPTO_BOX_MACBYTES);
     443}
     444if (!defined('\\Sodium\\CRYPTO_BOX_NONCEBYTES')) {
     445    define('\\Sodium\\CRYPTO_BOX_NONCEBYTES', ParagonIE_Sodium_Compat::CRYPTO_BOX_NONCEBYTES);
     446}
     447if (!defined('\\Sodium\\CRYPTO_BOX_SEEDBYTES')) {
     448    define('\\Sodium\\CRYPTO_BOX_SEEDBYTES', ParagonIE_Sodium_Compat::CRYPTO_BOX_SEEDBYTES);
     449}
     450if (!defined('\\Sodium\\CRYPTO_KX_BYTES')) {
     451    define('\\Sodium\\CRYPTO_KX_BYTES', ParagonIE_Sodium_Compat::CRYPTO_KX_BYTES);
     452}
     453if (!defined('\\Sodium\\CRYPTO_KX_PUBLICKEYBYTES')) {
     454    define('\\Sodium\\CRYPTO_KX_PUBLICKEYBYTES', ParagonIE_Sodium_Compat::CRYPTO_KX_PUBLICKEYBYTES);
     455}
     456if (!defined('\\Sodium\\CRYPTO_KX_SECRETKEYBYTES')) {
     457    define('\\Sodium\\CRYPTO_KX_SECRETKEYBYTES', ParagonIE_Sodium_Compat::CRYPTO_KX_SECRETKEYBYTES);
     458}
     459if (!defined('\\Sodium\\CRYPTO_GENERICHASH_BYTES')) {
     460    define('\\Sodium\\CRYPTO_GENERICHASH_BYTES', ParagonIE_Sodium_Compat::CRYPTO_GENERICHASH_BYTES);
     461}
     462if (!defined('\\Sodium\\CRYPTO_GENERICHASH_BYTES_MIN')) {
     463    define('\\Sodium\\CRYPTO_GENERICHASH_BYTES_MIN', ParagonIE_Sodium_Compat::CRYPTO_GENERICHASH_BYTES_MIN);
     464}
     465if (!defined('\\Sodium\\CRYPTO_GENERICHASH_BYTES_MAX')) {
     466    define('\\Sodium\\CRYPTO_GENERICHASH_BYTES_MAX', ParagonIE_Sodium_Compat::CRYPTO_GENERICHASH_BYTES_MAX);
     467}
     468if (!defined('\\Sodium\\CRYPTO_GENERICHASH_KEYBYTES')) {
     469    define('\\Sodium\\CRYPTO_GENERICHASH_KEYBYTES', ParagonIE_Sodium_Compat::CRYPTO_GENERICHASH_KEYBYTES);
     470}
     471if (!defined('\\Sodium\\CRYPTO_GENERICHASH_KEYBYTES_MIN')) {
     472    define('\\Sodium\\CRYPTO_GENERICHASH_KEYBYTES_MIN', ParagonIE_Sodium_Compat::CRYPTO_GENERICHASH_KEYBYTES_MIN);
     473}
     474if (!defined('\\Sodium\\CRYPTO_GENERICHASH_KEYBYTES_MAX')) {
     475    define('\\Sodium\\CRYPTO_GENERICHASH_KEYBYTES_MAX', ParagonIE_Sodium_Compat::CRYPTO_GENERICHASH_KEYBYTES_MAX);
     476}
     477if (!defined('\\Sodium\\CRYPTO_SCALARMULT_BYTES')) {
     478    define('\\Sodium\\CRYPTO_SCALARMULT_BYTES', ParagonIE_Sodium_Compat::CRYPTO_SCALARMULT_BYTES);
     479}
     480if (!defined('\\Sodium\\CRYPTO_SCALARMULT_SCALARBYTES')) {
     481    define('\\Sodium\\CRYPTO_SCALARMULT_SCALARBYTES', ParagonIE_Sodium_Compat::CRYPTO_SCALARMULT_SCALARBYTES);
     482}
     483if (!defined('\\Sodium\\CRYPTO_SHORTHASH_BYTES')) {
     484    define('\\Sodium\\CRYPTO_SHORTHASH_BYTES', ParagonIE_Sodium_Compat::CRYPTO_SHORTHASH_BYTES);
     485}
     486if (!defined('\\Sodium\\CRYPTO_SHORTHASH_KEYBYTES')) {
     487    define('\\Sodium\\CRYPTO_SHORTHASH_KEYBYTES', ParagonIE_Sodium_Compat::CRYPTO_SHORTHASH_KEYBYTES);
     488}
     489if (!defined('\\Sodium\\CRYPTO_SECRETBOX_KEYBYTES')) {
     490    define('\\Sodium\\CRYPTO_SECRETBOX_KEYBYTES', ParagonIE_Sodium_Compat::CRYPTO_SECRETBOX_KEYBYTES);
     491}
     492if (!defined('\\Sodium\\CRYPTO_SECRETBOX_MACBYTES')) {
     493    define('\\Sodium\\CRYPTO_SECRETBOX_MACBYTES', ParagonIE_Sodium_Compat::CRYPTO_SECRETBOX_MACBYTES);
     494}
     495if (!defined('\\Sodium\\CRYPTO_SECRETBOX_NONCEBYTES')) {
     496    define('\\Sodium\\CRYPTO_SECRETBOX_NONCEBYTES', ParagonIE_Sodium_Compat::CRYPTO_SECRETBOX_NONCEBYTES);
     497}
     498if (!defined('\\Sodium\\CRYPTO_SIGN_BYTES')) {
     499    define('\\Sodium\\CRYPTO_SIGN_BYTES', ParagonIE_Sodium_Compat::CRYPTO_SIGN_BYTES);
     500}
     501if (!defined('\\Sodium\\CRYPTO_SIGN_SEEDBYTES')) {
     502    define('\\Sodium\\CRYPTO_SIGN_SEEDBYTES', ParagonIE_Sodium_Compat::CRYPTO_SIGN_SEEDBYTES);
     503}
     504if (!defined('\\Sodium\\CRYPTO_SIGN_PUBLICKEYBYTES')) {
     505    define('\\Sodium\\CRYPTO_SIGN_PUBLICKEYBYTES', ParagonIE_Sodium_Compat::CRYPTO_SIGN_PUBLICKEYBYTES);
     506}
     507if (!defined('\\Sodium\\CRYPTO_SIGN_SECRETKEYBYTES')) {
     508    define('\\Sodium\\CRYPTO_SIGN_SECRETKEYBYTES', ParagonIE_Sodium_Compat::CRYPTO_SIGN_SECRETKEYBYTES);
     509}
     510if (!defined('\\Sodium\\CRYPTO_SIGN_KEYPAIRBYTES')) {
     511    define('\\Sodium\\CRYPTO_SIGN_KEYPAIRBYTES', ParagonIE_Sodium_Compat::CRYPTO_SIGN_KEYPAIRBYTES);
     512}
     513if (!defined('\\Sodium\\CRYPTO_STREAM_KEYBYTES')) {
     514    define('\\Sodium\\CRYPTO_STREAM_KEYBYTES', ParagonIE_Sodium_Compat::CRYPTO_STREAM_KEYBYTES);
     515}
     516if (!defined('\\Sodium\\CRYPTO_STREAM_NONCEBYTES')) {
     517    define('\\Sodium\\CRYPTO_STREAM_NONCEBYTES', ParagonIE_Sodium_Compat::CRYPTO_STREAM_NONCEBYTES);
     518}
  • wp-includes/sodium_compat/src/Core/HSalsa20.php

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
     1<?php
     2
     3/**
     4 * Class ParagonIE_Sodium_Core_HSalsa20
     5 */
     6abstract class ParagonIE_Sodium_Core_HSalsa20 extends ParagonIE_Sodium_Core_Salsa20
     7{
     8    /**
     9     * Calculate an hsalsa20 hash of a single block
     10     *
     11     * @param string $in
     12     * @param string $k
     13     * @param string|null $c
     14     * @return string
     15     */
     16    public static function hsalsa20($in, $k, $c = null)
     17    {
     18        if ($c === null) {
     19            $x0  = 0x61707865;
     20            $x5  = 0x3320646e;
     21            $x10 = 0x79622d32;
     22            $x15 = 0x6b206574;
     23        } else {
     24            $x0  = self::load_4(self::substr($c,  0, 4));
     25            $x5  = self::load_4(self::substr($c,  4, 4));
     26            $x10 = self::load_4(self::substr($c,  8, 4));
     27            $x15 = self::load_4(self::substr($c, 12, 4));
     28        }
     29        $x1  = self::load_4(self::substr($k,  0, 4));
     30        $x2  = self::load_4(self::substr($k,  4, 4));
     31        $x3  = self::load_4(self::substr($k,  8, 4));
     32        $x4  = self::load_4(self::substr($k, 12, 4));
     33        $x11 = self::load_4(self::substr($k, 16, 4));
     34        $x12 = self::load_4(self::substr($k, 20, 4));
     35        $x13 = self::load_4(self::substr($k, 24, 4));
     36        $x14 = self::load_4(self::substr($k, 28, 4));
     37        $x6  = self::load_4(self::substr($in, 0, 4));
     38        $x7  = self::load_4(self::substr($in, 4, 4));
     39        $x8  = self::load_4(self::substr($in, 8, 4));
     40        $x9  = self::load_4(self::substr($in, 12, 4));
     41
     42        for ($i = self::ROUNDS; $i > 0; $i -= 2) {
     43            $x4 ^= self::rotate($x0 + $x12, 7);
     44            $x8 ^= self::rotate($x4 + $x0, 9);
     45            $x12 ^= self::rotate($x8 + $x4, 13);
     46            $x0 ^= self::rotate($x12 + $x8, 18);
     47            $x9 ^= self::rotate($x5 + $x1, 7);
     48            $x13 ^= self::rotate($x9 + $x5, 9);
     49            $x1 ^= self::rotate($x13 + $x9, 13);
     50            $x5 ^= self::rotate($x1 + $x13, 18);
     51            $x14 ^= self::rotate($x10 + $x6, 7);
     52            $x2 ^= self::rotate($x14 + $x10, 9);
     53            $x6 ^= self::rotate($x2 + $x14, 13);
     54            $x10 ^= self::rotate($x6 + $x2, 18);
     55            $x3 ^= self::rotate($x15 + $x11, 7);
     56            $x7 ^= self::rotate($x3 + $x15, 9);
     57            $x11 ^= self::rotate($x7 + $x3, 13);
     58            $x15 ^= self::rotate($x11 + $x7, 18);
     59            $x1 ^= self::rotate($x0 + $x3, 7);
     60            $x2 ^= self::rotate($x1 + $x0, 9);
     61            $x3 ^= self::rotate($x2 + $x1, 13);
     62            $x0 ^= self::rotate($x3 + $x2, 18);
     63            $x6 ^= self::rotate($x5 + $x4, 7);
     64            $x7 ^= self::rotate($x6 + $x5, 9);
     65            $x4 ^= self::rotate($x7 + $x6, 13);
     66            $x5 ^= self::rotate($x4 + $x7, 18);
     67            $x11 ^= self::rotate($x10 + $x9, 7);
     68            $x8 ^= self::rotate($x11 + $x10, 9);
     69            $x9 ^= self::rotate($x8 + $x11, 13);
     70            $x10 ^= self::rotate($x9 + $x8, 18);
     71            $x12 ^= self::rotate($x15 + $x14, 7);
     72            $x13 ^= self::rotate($x12 + $x15, 9);
     73            $x14 ^= self::rotate($x13 + $x12, 13);
     74            $x15 ^= self::rotate($x14 + $x13, 18);
     75        }
     76
     77        return self::store32_le($x0) .
     78            self::store32_le($x5) .
     79            self::store32_le($x10) .
     80            self::store32_le($x15) .
     81            self::store32_le($x6) .
     82            self::store32_le($x7) .
     83            self::store32_le($x8) .
     84            self::store32_le($x9);
     85    }
     86}
  • wp-includes/sodium_compat/src/Core/Curve25519/Fe.php

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
     1<?php
     2
     3/**
     4 * Class ParagonIE_Sodium_Core_Curve25519_Fe
     5 *
     6 * This represents a Field Element
     7 */
     8class ParagonIE_Sodium_Core_Curve25519_Fe implements ArrayAccess
     9{
     10    /**
     11     * @var array
     12     */
     13    protected $container = array();
     14
     15    /**
     16     * @var int
     17     */
     18    protected $size = 10;
     19
     20    /**
     21     * ParagonIE_Sodium_Core_Curve25519_Fe constructor.
     22     * @param int $size
     23     */
     24    public function __construct($size = 10)
     25    {
     26        $this->size = 10;
     27    }
     28
     29    /**
     30     * @param array $array
     31     * @param bool $save_indexes
     32     * @return self
     33     */
     34    public static function fromArray($array, $save_indexes = null)
     35    {
     36        $count = count($array);
     37        if ($save_indexes) {
     38            $keys = array_keys($array);
     39        } else {
     40            $keys = range(0, $count - 1);
     41        }
     42        $array = array_values($array);
     43
     44        $obj = new ParagonIE_Sodium_Core_Curve25519_Fe($count);
     45        if ($save_indexes) {
     46            for ($i = 0; $i < $count; ++$i) {
     47                $obj->offsetSet($keys[$i], $array[$i]);
     48            }
     49        } else {
     50            for ($i = 0; $i < $count; ++$i) {
     51                $obj->offsetSet($i, $array[$i]);
     52            }
     53        }
     54        return $obj;
     55    }
     56
     57    /**
     58     * @param mixed $offset
     59     * @param mixed $value
     60     */
     61    public function offsetSet($offset, $value)
     62    {
     63        if (!is_int($value)) {
     64            throw new InvalidArgumentException('Expected an integer');
     65        }
     66        if (is_null($offset)) {
     67            $this->container[] = $value;
     68        } else {
     69            $this->container[$offset] = $value;
     70        }
     71    }
     72
     73    /**
     74     * @param mixed $offset
     75     * @return bool
     76     */
     77    public function offsetExists($offset)
     78    {
     79        return isset($this->container[$offset]);
     80    }
     81
     82    /**
     83     * @param mixed $offset
     84     */
     85    public function offsetUnset($offset)
     86    {
     87        unset($this->container[$offset]);
     88    }
     89
     90    /**
     91     * @param mixed $offset
     92     * @return mixed|null
     93     */
     94    public function offsetGet($offset)
     95    {
     96        return isset($this->container[$offset])
     97            ? $this->container[$offset]
     98            : null;
     99    }
     100
     101    /**
     102     * @return array
     103     */
     104    public function __debugInfo()
     105    {
     106        return array(implode(', ', $this->container));
     107    }
     108}
  • wp-includes/sodium_compat/src/Core/Curve25519/H.php

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
     1<?php
     2
     3/**
     4 * Class ParagonIE_Sodium_Core_Curve25519_H
     5 */
     6class ParagonIE_Sodium_Core_Curve25519_H extends ParagonIE_Sodium_Core_Util
     7{
     8    /**
     9     * See: libsodium's crypto_core/curve25519/ref10/base.h
     10     *
     11     * @var array Basically, int[32][8][3][10]
     12     */
     13    protected static $base = array(
     14        array(
     15            array(
     16                array(25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626, -11754271, -6079156, 2047605),
     17                array(-12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692, 5043384, 19500929, -15469378),
     18                array(-8738181, 4489570, 9688441, -14785194, 10184609, -12363380, 29287919, 11864899, -24514362, -4438546),
     19            ),
     20            array(
     21                array(-12815894, -12976347, -21581243, 11784320, -25355658, -2750717, -11717903, -3814571, -358445, -10211303),
     22                array(-21703237, 6903825, 27185491, 6451973, -29577724, -9554005, -15616551, 11189268, -26829678, -5319081),
     23                array(26966642, 11152617, 32442495, 15396054, 14353839, -12752335, -3128826, -9541118, -15472047, -4166697),
     24            ),
     25            array(
     26                array(15636291, -9688557, 24204773, -7912398, 616977, -16685262, 27787600, -14772189, 28944400, -1550024),
     27                array(16568933, 4717097, -11556148, -1102322, 15682896, -11807043, 16354577, -11775962, 7689662, 11199574),
     28                array(30464156, -5976125, -11779434, -15670865, 23220365, 15915852, 7512774, 10017326, -17749093, -9920357),
     29            ),
     30            array(
     31                array(-17036878, 13921892, 10945806, -6033431, 27105052, -16084379, -28926210, 15006023, 3284568, -6276540),
     32                array(23599295, -8306047, -11193664, -7687416, 13236774, 10506355, 7464579, 9656445, 13059162, 10374397),
     33                array(7798556, 16710257, 3033922, 2874086, 28997861, 2835604, 32406664, -3839045, -641708, -101325),
     34            ),
     35            array(
     36                array(10861363, 11473154, 27284546, 1981175, -30064349, 12577861, 32867885, 14515107, -15438304, 10819380),
     37                array(4708026, 6336745, 20377586, 9066809, -11272109, 6594696, -25653668, 12483688, -12668491, 5581306),
     38                array(19563160, 16186464, -29386857, 4097519, 10237984, -4348115, 28542350, 13850243, -23678021, -15815942),
     39            ),
     40            array(
     41                array(-15371964, -12862754, 32573250, 4720197, -26436522, 5875511, -19188627, -15224819, -9818940, -12085777),
     42                array(-8549212, 109983, 15149363, 2178705, 22900618, 4543417, 3044240, -15689887, 1762328, 14866737),
     43                array(-18199695, -15951423, -10473290, 1707278, -17185920, 3916101, -28236412, 3959421, 27914454, 4383652),
     44            ),
     45            array(
     46                array(5153746, 9909285, 1723747, -2777874, 30523605, 5516873, 19480852, 5230134, -23952439, -15175766),
     47                array(-30269007, -3463509, 7665486, 10083793, 28475525, 1649722, 20654025, 16520125, 30598449, 7715701),
     48                array(28881845, 14381568, 9657904, 3680757, -20181635, 7843316, -31400660, 1370708, 29794553, -1409300),
     49            ),
     50            array(
     51                array(14499471, -2729599, -33191113, -4254652, 28494862, 14271267, 30290735, 10876454, -33154098, 2381726),
     52                array(-7195431, -2655363, -14730155, 462251, -27724326, 3941372, -6236617, 3696005, -32300832, 15351955),
     53                array(27431194, 8222322, 16448760, -3907995, -18707002, 11938355, -32961401, -2970515, 29551813, 10109425),
     54            ),
     55        ),
     56        array(
     57            array(
     58                array(-13657040, -13155431, -31283750, 11777098, 21447386, 6519384, -2378284, -1627556, 10092783, -4764171),
     59                array(27939166, 14210322, 4677035, 16277044, -22964462, -12398139, -32508754, 12005538, -17810127, 12803510),
     60                array(17228999, -15661624, -1233527, 300140, -1224870, -11714777, 30364213, -9038194, 18016357, 4397660),
     61            ),
     62            array(
     63                array(-10958843, -7690207, 4776341, -14954238, 27850028, -15602212, -26619106, 14544525, -17477504, 982639),
     64                array(29253598, 15796703, -2863982, -9908884, 10057023, 3163536, 7332899, -4120128, -21047696, 9934963),
     65                array(5793303, 16271923, -24131614, -10116404, 29188560, 1206517, -14747930, 4559895, -30123922, -10897950),
     66            ),
     67            array(
     68                array(-27643952, -11493006, 16282657, -11036493, 28414021, -15012264, 24191034, 4541697, -13338309, 5500568),
     69                array(12650548, -1497113, 9052871, 11355358, -17680037, -8400164, -17430592, 12264343, 10874051, 13524335),
     70                array(25556948, -3045990, 714651, 2510400, 23394682, -10415330, 33119038, 5080568, -22528059, 5376628),
     71            ),
     72            array(
     73                array(-26088264, -4011052, -17013699, -3537628, -6726793, 1920897, -22321305, -9447443, 4535768, 1569007),
     74                array(-2255422, 14606630, -21692440, -8039818, 28430649, 8775819, -30494562, 3044290, 31848280, 12543772),
     75                array(-22028579, 2943893, -31857513, 6777306, 13784462, -4292203, -27377195, -2062731, 7718482, 14474653),
     76            ),
     77            array(
     78                array(2385315, 2454213, -22631320, 46603, -4437935, -15680415, 656965, -7236665, 24316168, -5253567),
     79                array(13741529, 10911568, -33233417, -8603737, -20177830, -1033297, 33040651, -13424532, -20729456, 8321686),
     80                array(21060490, -2212744, 15712757, -4336099, 1639040, 10656336, 23845965, -11874838, -9984458, 608372),
     81            ),
     82            array(
     83                array(-13672732, -15087586, -10889693, -7557059, -6036909, 11305547, 1123968, -6780577, 27229399, 23887),
     84                array(-23244140, -294205, -11744728, 14712571, -29465699, -2029617, 12797024, -6440308, -1633405, 16678954),
     85                array(-29500620, 4770662, -16054387, 14001338, 7830047, 9564805, -1508144, -4795045, -17169265, 4904953),
     86            ),
     87            array(
     88                array(24059557, 14617003, 19037157, -15039908, 19766093, -14906429, 5169211, 16191880, 2128236, -4326833),
     89                array(-16981152, 4124966, -8540610, -10653797, 30336522, -14105247, -29806336, 916033, -6882542, -2986532),
     90                array(-22630907, 12419372, -7134229, -7473371, -16478904, 16739175, 285431, 2763829, 15736322, 4143876),
     91            ),
     92            array(
     93                array(2379352, 11839345, -4110402, -5988665, 11274298, 794957, 212801, -14594663, 23527084, -16458268),
     94                array(33431127, -11130478, -17838966, -15626900, 8909499, 8376530, -32625340, 4087881, -15188911, -14416214),
     95                array(1767683, 7197987, -13205226, -2022635, -13091350, 448826, 5799055, 4357868, -4774191, -16323038),
     96            ),
     97        ),
     98        array(
     99            array(
     100                array(6721966, 13833823, -23523388, -1551314, 26354293, -11863321, 23365147, -3949732, 7390890, 2759800),
     101                array(4409041, 2052381, 23373853, 10530217, 7676779, -12885954, 21302353, -4264057, 1244380, -12919645),
     102                array(-4421239, 7169619, 4982368, -2957590, 30256825, -2777540, 14086413, 9208236, 15886429, 16489664),
     103            ),
     104            array(
     105                array(1996075, 10375649, 14346367, 13311202, -6874135, -16438411, -13693198, 398369, -30606455, -712933),
     106                array(-25307465, 9795880, -2777414, 14878809, -33531835, 14780363, 13348553, 12076947, -30836462, 5113182),
     107                array(-17770784, 11797796, 31950843, 13929123, -25888302, 12288344, -30341101, -7336386, 13847711, 5387222),
     108            ),
     109            array(
     110                array(-18582163, -3416217, 17824843, -2340966, 22744343, -10442611, 8763061, 3617786, -19600662, 10370991),
     111                array(20246567, -14369378, 22358229, -543712, 18507283, -10413996, 14554437, -8746092, 32232924, 16763880),
     112                array(9648505, 10094563, 26416693, 14745928, -30374318, -6472621, 11094161, 15689506, 3140038, -16510092),
     113            ),
     114            array(
     115                array(-16160072, 5472695, 31895588, 4744994, 8823515, 10365685, -27224800, 9448613, -28774454, 366295),
     116                array(19153450, 11523972, -11096490, -6503142, -24647631, 5420647, 28344573, 8041113, 719605, 11671788),
     117                array(8678025, 2694440, -6808014, 2517372, 4964326, 11152271, -15432916, -15266516, 27000813, -10195553),
     118            ),
     119            array(
     120                array(-15157904, 7134312, 8639287, -2814877, -7235688, 10421742, 564065, 5336097, 6750977, -14521026),
     121                array(11836410, -3979488, 26297894, 16080799, 23455045, 15735944, 1695823, -8819122, 8169720, 16220347),
     122                array(-18115838, 8653647, 17578566, -6092619, -8025777, -16012763, -11144307, -2627664, -5990708, -14166033),
     123            ),
     124            array(
     125                array(-23308498, -10968312, 15213228, -10081214, -30853605, -11050004, 27884329, 2847284, 2655861, 1738395),
     126                array(-27537433, -14253021, -25336301, -8002780, -9370762, 8129821, 21651608, -3239336, -19087449, -11005278),
     127                array(1533110, 3437855, 23735889, 459276, 29970501, 11335377, 26030092, 5821408, 10478196, 8544890),
     128            ),
     129            array(
     130                array(32173121, -16129311, 24896207, 3921497, 22579056, -3410854, 19270449, 12217473, 17789017, -3395995),
     131                array(-30552961, -2228401, -15578829, -10147201, 13243889, 517024, 15479401, -3853233, 30460520, 1052596),
     132                array(-11614875, 13323618, 32618793, 8175907, -15230173, 12596687, 27491595, -4612359, 3179268, -9478891),
     133            ),
     134            array(
     135                array(31947069, -14366651, -4640583, -15339921, -15125977, -6039709, -14756777, -16411740, 19072640, -9511060),
     136                array(11685058, 11822410, 3158003, -13952594, 33402194, -4165066, 5977896, -5215017, 473099, 5040608),
     137                array(-20290863, 8198642, -27410132, 11602123, 1290375, -2799760, 28326862, 1721092, -19558642, -3131606),
     138            ),
     139        ),
     140        array(
     141            array(
     142                array(7881532, 10687937, 7578723, 7738378, -18951012, -2553952, 21820786, 8076149, -27868496, 11538389),
     143                array(-19935666, 3899861, 18283497, -6801568, -15728660, -11249211, 8754525, 7446702, -5676054, 5797016),
     144                array(-11295600, -3793569, -15782110, -7964573, 12708869, -8456199, 2014099, -9050574, -2369172, -5877341),
     145            ),
     146            array(
     147                array(-22472376, -11568741, -27682020, 1146375, 18956691, 16640559, 1192730, -3714199, 15123619, 10811505),
     148                array(14352098, -3419715, -18942044, 10822655, 32750596, 4699007, -70363, 15776356, -28886779, -11974553),
     149                array(-28241164, -8072475, -4978962, -5315317, 29416931, 1847569, -20654173, -16484855, 4714547, -9600655),
     150            ),
     151            array(
     152                array(15200332, 8368572, 19679101, 15970074, -31872674, 1959451, 24611599, -4543832, -11745876, 12340220),
     153                array(12876937, -10480056, 33134381, 6590940, -6307776, 14872440, 9613953, 8241152, 15370987, 9608631),
     154                array(-4143277, -12014408, 8446281, -391603, 4407738, 13629032, -7724868, 15866074, -28210621, -8814099),
     155            ),
     156            array(
     157                array(26660628, -15677655, 8393734, 358047, -7401291, 992988, -23904233, 858697, 20571223, 8420556),
     158                array(14620715, 13067227, -15447274, 8264467, 14106269, 15080814, 33531827, 12516406, -21574435, -12476749),
     159                array(236881, 10476226, 57258, -14677024, 6472998, 2466984, 17258519, 7256740, 8791136, 15069930),
     160            ),
     161            array(
     162                array(1276410, -9371918, 22949635, -16322807, -23493039, -5702186, 14711875, 4874229, -30663140, -2331391),
     163                array(5855666, 4990204, -13711848, 7294284, -7804282, 1924647, -1423175, -7912378, -33069337, 9234253),
     164                array(20590503, -9018988, 31529744, -7352666, -2706834, 10650548, 31559055, -11609587, 18979186, 13396066),
     165            ),
     166            array(
     167                array(24474287, 4968103, 22267082, 4407354, 24063882, -8325180, -18816887, 13594782, 33514650, 7021958),
     168                array(-11566906, -6565505, -21365085, 15928892, -26158305, 4315421, -25948728, -3916677, -21480480, 12868082),
     169                array(-28635013, 13504661, 19988037, -2132761, 21078225, 6443208, -21446107, 2244500, -12455797, -8089383),
     170            ),
     171            array(
     172                array(-30595528, 13793479, -5852820, 319136, -25723172, -6263899, 33086546, 8957937, -15233648, 5540521),
     173                array(-11630176, -11503902, -8119500, -7643073, 2620056, 1022908, -23710744, -1568984, -16128528, -14962807),
     174                array(23152971, 775386, 27395463, 14006635, -9701118, 4649512, 1689819, 892185, -11513277, -15205948),
     175            ),
     176            array(
     177                array(9770129, 9586738, 26496094, 4324120, 1556511, -3550024, 27453819, 4763127, -19179614, 5867134),
     178                array(-32765025, 1927590, 31726409, -4753295, 23962434, -16019500, 27846559, 5931263, -29749703, -16108455),
     179                array(27461885, -2977536, 22380810, 1815854, -23033753, -3031938, 7283490, -15148073, -19526700, 7734629),
     180            ),
     181        ),
     182        array(
     183            array(
     184                array(-8010264, -9590817, -11120403, 6196038, 29344158, -13430885, 7585295, -3176626, 18549497, 15302069),
     185                array(-32658337, -6171222, -7672793, -11051681, 6258878, 13504381, 10458790, -6418461, -8872242, 8424746),
     186                array(24687205, 8613276, -30667046, -3233545, 1863892, -1830544, 19206234, 7134917, -11284482, -828919),
     187            ),
     188            array(
     189                array(11334899, -9218022, 8025293, 12707519, 17523892, -10476071, 10243738, -14685461, -5066034, 16498837),
     190                array(8911542, 6887158, -9584260, -6958590, 11145641, -9543680, 17303925, -14124238, 6536641, 10543906),
     191                array(-28946384, 15479763, -17466835, 568876, -1497683, 11223454, -2669190, -16625574, -27235709, 8876771),
     192            ),
     193            array(
     194                array(-25742899, -12566864, -15649966, -846607, -33026686, -796288, -33481822, 15824474, -604426, -9039817),
     195                array(10330056, 70051, 7957388, -9002667, 9764902, 15609756, 27698697, -4890037, 1657394, 3084098),
     196                array(10477963, -7470260, 12119566, -13250805, 29016247, -5365589, 31280319, 14396151, -30233575, 15272409),
     197            ),
     198            array(
     199                array(-12288309, 3169463, 28813183, 16658753, 25116432, -5630466, -25173957, -12636138, -25014757, 1950504),
     200                array(-26180358, 9489187, 11053416, -14746161, -31053720, 5825630, -8384306, -8767532, 15341279, 8373727),
     201                array(28685821, 7759505, -14378516, -12002860, -31971820, 4079242, 298136, -10232602, -2878207, 15190420),
     202            ),
     203            array(
     204                array(-32932876, 13806336, -14337485, -15794431, -24004620, 10940928, 8669718, 2742393, -26033313, -6875003),
     205                array(-1580388, -11729417, -25979658, -11445023, -17411874, -10912854, 9291594, -16247779, -12154742, 6048605),
     206                array(-30305315, 14843444, 1539301, 11864366, 20201677, 1900163, 13934231, 5128323, 11213262, 9168384),
     207            ),
     208            array(
     209                array(-26280513, 11007847, 19408960, -940758, -18592965, -4328580, -5088060, -11105150, 20470157, -16398701),
     210                array(-23136053, 9282192, 14855179, -15390078, -7362815, -14408560, -22783952, 14461608, 14042978, 5230683),
     211                array(29969567, -2741594, -16711867, -8552442, 9175486, -2468974, 21556951, 3506042, -5933891, -12449708),
     212            ),
     213            array(
     214                array(-3144746, 8744661, 19704003, 4581278, -20430686, 6830683, -21284170, 8971513, -28539189, 15326563),
     215                array(-19464629, 10110288, -17262528, -3503892, -23500387, 1355669, -15523050, 15300988, -20514118, 9168260),
     216                array(-5353335, 4488613, -23803248, 16314347, 7780487, -15638939, -28948358, 9601605, 33087103, -9011387),
     217            ),
     218            array(
     219                array(-19443170, -15512900, -20797467, -12445323, -29824447, 10229461, -27444329, -15000531, -5996870, 15664672),
     220                array(23294591, -16632613, -22650781, -8470978, 27844204, 11461195, 13099750, -2460356, 18151676, 13417686),
     221                array(-24722913, -4176517, -31150679, 5988919, -26858785, 6685065, 1661597, -12551441, 15271676, -15452665),
     222            ),
     223        ),
     224        array(
     225            array(
     226                array(11433042, -13228665, 8239631, -5279517, -1985436, -725718, -18698764, 2167544, -6921301, -13440182),
     227                array(-31436171, 15575146, 30436815, 12192228, -22463353, 9395379, -9917708, -8638997, 12215110, 12028277),
     228                array(14098400, 6555944, 23007258, 5757252, -15427832, -12950502, 30123440, 4617780, -16900089, -655628),
     229            ),
     230            array(
     231                array(-4026201, -15240835, 11893168, 13718664, -14809462, 1847385, -15819999, 10154009, 23973261, -12684474),
     232                array(-26531820, -3695990, -1908898, 2534301, -31870557, -16550355, 18341390, -11419951, 32013174, -10103539),
     233                array(-25479301, 10876443, -11771086, -14625140, -12369567, 1838104, 21911214, 6354752, 4425632, -837822),
     234            ),
     235            array(
     236                array(-10433389, -14612966, 22229858, -3091047, -13191166, 776729, -17415375, -12020462, 4725005, 14044970),
     237                array(19268650, -7304421, 1555349, 8692754, -21474059, -9910664, 6347390, -1411784, -19522291, -16109756),
     238                array(-24864089, 12986008, -10898878, -5558584, -11312371, -148526, 19541418, 8180106, 9282262, 10282508),
     239            ),
     240            array(
     241                array(-26205082, 4428547, -8661196, -13194263, 4098402, -14165257, 15522535, 8372215, 5542595, -10702683),
     242                array(-10562541, 14895633, 26814552, -16673850, -17480754, -2489360, -2781891, 6993761, -18093885, 10114655),
     243                array(-20107055, -929418, 31422704, 10427861, -7110749, 6150669, -29091755, -11529146, 25953725, -106158),
     244            ),
     245            array(
     246                array(-4234397, -8039292, -9119125, 3046000, 2101609, -12607294, 19390020, 6094296, -3315279, 12831125),
     247                array(-15998678, 7578152, 5310217, 14408357, -33548620, -224739, 31575954, 6326196, 7381791, -2421839),
     248                array(-20902779, 3296811, 24736065, -16328389, 18374254, 7318640, 6295303, 8082724, -15362489, 12339664),
     249            ),
     250            array(
     251                array(27724736, 2291157, 6088201, -14184798, 1792727, 5857634, 13848414, 15768922, 25091167, 14856294),
     252                array(-18866652, 8331043, 24373479, 8541013, -701998, -9269457, 12927300, -12695493, -22182473, -9012899),
     253                array(-11423429, -5421590, 11632845, 3405020, 30536730, -11674039, -27260765, 13866390, 30146206, 9142070),
     254            ),
     255            array(
     256                array(3924129, -15307516, -13817122, -10054960, 12291820, -668366, -27702774, 9326384, -8237858, 4171294),
     257                array(-15921940, 16037937, 6713787, 16606682, -21612135, 2790944, 26396185, 3731949, 345228, -5462949),
     258                array(-21327538, 13448259, 25284571, 1143661, 20614966, -8849387, 2031539, -12391231, -16253183, -13582083),
     259            ),
     260            array(
     261                array(31016211, -16722429, 26371392, -14451233, -5027349, 14854137, 17477601, 3842657, 28012650, -16405420),
     262                array(-5075835, 9368966, -8562079, -4600902, -15249953, 6970560, -9189873, 16292057, -8867157, 3507940),
     263                array(29439664, 3537914, 23333589, 6997794, -17555561, -11018068, -15209202, -15051267, -9164929, 6580396),
     264            ),
     265        ),
     266        array(
     267            array(
     268                array(-12185861, -7679788, 16438269, 10826160, -8696817, -6235611, 17860444, -9273846, -2095802, 9304567),
     269                array(20714564, -4336911, 29088195, 7406487, 11426967, -5095705, 14792667, -14608617, 5289421, -477127),
     270                array(-16665533, -10650790, -6160345, -13305760, 9192020, -1802462, 17271490, 12349094, 26939669, -3752294),
     271            ),
     272            array(
     273                array(-12889898, 9373458, 31595848, 16374215, 21471720, 13221525, -27283495, -12348559, -3698806, 117887),
     274                array(22263325, -6560050, 3984570, -11174646, -15114008, -566785, 28311253, 5358056, -23319780, 541964),
     275                array(16259219, 3261970, 2309254, -15534474, -16885711, -4581916, 24134070, -16705829, -13337066, -13552195),
     276            ),
     277            array(
     278                array(9378160, -13140186, -22845982, -12745264, 28198281, -7244098, -2399684, -717351, 690426, 14876244),
     279                array(24977353, -314384, -8223969, -13465086, 28432343, -1176353, -13068804, -12297348, -22380984, 6618999),
     280                array(-1538174, 11685646, 12944378, 13682314, -24389511, -14413193, 8044829, -13817328, 32239829, -5652762),
     281            ),
     282            array(
     283                array(-18603066, 4762990, -926250, 8885304, -28412480, -3187315, 9781647, -10350059, 32779359, 5095274),
     284                array(-33008130, -5214506, -32264887, -3685216, 9460461, -9327423, -24601656, 14506724, 21639561, -2630236),
     285                array(-16400943, -13112215, 25239338, 15531969, 3987758, -4499318, -1289502, -6863535, 17874574, 558605),
     286            ),
     287            array(
     288                array(-13600129, 10240081, 9171883, 16131053, -20869254, 9599700, 33499487, 5080151, 2085892, 5119761),
     289                array(-22205145, -2519528, -16381601, 414691, -25019550, 2170430, 30634760, -8363614, -31999993, -5759884),
     290                array(-6845704, 15791202, 8550074, -1312654, 29928809, -12092256, 27534430, -7192145, -22351378, 12961482),
     291            ),
     292            array(
     293                array(-24492060, -9570771, 10368194, 11582341, -23397293, -2245287, 16533930, 8206996, -30194652, -5159638),
     294                array(-11121496, -3382234, 2307366, 6362031, -135455, 8868177, -16835630, 7031275, 7589640, 8945490),
     295                array(-32152748, 8917967, 6661220, -11677616, -1192060, -15793393, 7251489, -11182180, 24099109, -14456170),
     296            ),
     297            array(
     298                array(5019558, -7907470, 4244127, -14714356, -26933272, 6453165, -19118182, -13289025, -6231896, -10280736),
     299                array(10853594, 10721687, 26480089, 5861829, -22995819, 1972175, -1866647, -10557898, -3363451, -6441124),
     300                array(-17002408, 5906790, 221599, -6563147, 7828208, -13248918, 24362661, -2008168, -13866408, 7421392),
     301            ),
     302            array(
     303                array(8139927, -6546497, 32257646, -5890546, 30375719, 1886181, -21175108, 15441252, 28826358, -4123029),
     304                array(6267086, 9695052, 7709135, -16603597, -32869068, -1886135, 14795160, -7840124, 13746021, -1742048),
     305                array(28584902, 7787108, -6732942, -15050729, 22846041, -7571236, -3181936, -363524, 4771362, -8419958),
     306            ),
     307        ),
     308        array(
     309            array(
     310                array(24949256, 6376279, -27466481, -8174608, -18646154, -9930606, 33543569, -12141695, 3569627, 11342593),
     311                array(26514989, 4740088, 27912651, 3697550, 19331575, -11472339, 6809886, 4608608, 7325975, -14801071),
     312                array(-11618399, -14554430, -24321212, 7655128, -1369274, 5214312, -27400540, 10258390, -17646694, -8186692),
     313            ),
     314            array(
     315                array(11431204, 15823007, 26570245, 14329124, 18029990, 4796082, -31446179, 15580664, 9280358, -3973687),
     316                array(-160783, -10326257, -22855316, -4304997, -20861367, -13621002, -32810901, -11181622, -15545091, 4387441),
     317                array(-20799378, 12194512, 3937617, -5805892, -27154820, 9340370, -24513992, 8548137, 20617071, -7482001),
     318            ),
     319            array(
     320                array(-938825, -3930586, -8714311, 16124718, 24603125, -6225393, -13775352, -11875822, 24345683, 10325460),
     321                array(-19855277, -1568885, -22202708, 8714034, 14007766, 6928528, 16318175, -1010689, 4766743, 3552007),
     322                array(-21751364, -16730916, 1351763, -803421, -4009670, 3950935, 3217514, 14481909, 10988822, -3994762),
     323            ),
     324            array(
     325                array(15564307, -14311570, 3101243, 5684148, 30446780, -8051356, 12677127, -6505343, -8295852, 13296005),
     326                array(-9442290, 6624296, -30298964, -11913677, -4670981, -2057379, 31521204, 9614054, -30000824, 12074674),
     327                array(4771191, -135239, 14290749, -13089852, 27992298, 14998318, -1413936, -1556716, 29832613, -16391035),
     328            ),
     329            array(
     330                array(7064884, -7541174, -19161962, -5067537, -18891269, -2912736, 25825242, 5293297, -27122660, 13101590),
     331                array(-2298563, 2439670, -7466610, 1719965, -27267541, -16328445, 32512469, -5317593, -30356070, -4190957),
     332                array(-30006540, 10162316, -33180176, 3981723, -16482138, -13070044, 14413974, 9515896, 19568978, 9628812),
     333            ),
     334            array(
     335                array(33053803, 199357, 15894591, 1583059, 27380243, -4580435, -17838894, -6106839, -6291786, 3437740),
     336                array(-18978877, 3884493, 19469877, 12726490, 15913552, 13614290, -22961733, 70104, 7463304, 4176122),
     337                array(-27124001, 10659917, 11482427, -16070381, 12771467, -6635117, -32719404, -5322751, 24216882, 5944158),
     338            ),
     339            array(
     340                array(8894125, 7450974, -2664149, -9765752, -28080517, -12389115, 19345746, 14680796, 11632993, 5847885),
     341                array(26942781, -2315317, 9129564, -4906607, 26024105, 11769399, -11518837, 6367194, -9727230, 4782140),
     342                array(19916461, -4828410, -22910704, -11414391, 25606324, -5972441, 33253853, 8220911, 6358847, -1873857),
     343            ),
     344            array(
     345                array(801428, -2081702, 16569428, 11065167, 29875704, 96627, 7908388, -4480480, -13538503, 1387155),
     346                array(19646058, 5720633, -11416706, 12814209, 11607948, 12749789, 14147075, 15156355, -21866831, 11835260),
     347                array(19299512, 1155910, 28703737, 14890794, 2925026, 7269399, 26121523, 15467869, -26560550, 5052483),
     348            ),
     349        ),
     350        array(
     351            array(
     352                array(-3017432, 10058206, 1980837, 3964243, 22160966, 12322533, -6431123, -12618185, 12228557, -7003677),
     353                array(32944382, 14922211, -22844894, 5188528, 21913450, -8719943, 4001465, 13238564, -6114803, 8653815),
     354                array(22865569, -4652735, 27603668, -12545395, 14348958, 8234005, 24808405, 5719875, 28483275, 2841751),
     355            ),
     356            array(
     357                array(-16420968, -1113305, -327719, -12107856, 21886282, -15552774, -1887966, -315658, 19932058, -12739203),
     358                array(-11656086, 10087521, -8864888, -5536143, -19278573, -3055912, 3999228, 13239134, -4777469, -13910208),
     359                array(1382174, -11694719, 17266790, 9194690, -13324356, 9720081, 20403944, 11284705, -14013818, 3093230),
     360            ),
     361            array(
     362                array(16650921, -11037932, -1064178, 1570629, -8329746, 7352753, -302424, 16271225, -24049421, -6691850),
     363                array(-21911077, -5927941, -4611316, -5560156, -31744103, -10785293, 24123614, 15193618, -21652117, -16739389),
     364                array(-9935934, -4289447, -25279823, 4372842, 2087473, 10399484, 31870908, 14690798, 17361620, 11864968),
     365            ),
     366            array(
     367                array(-11307610, 6210372, 13206574, 5806320, -29017692, -13967200, -12331205, -7486601, -25578460, -16240689),
     368                array(14668462, -12270235, 26039039, 15305210, 25515617, 4542480, 10453892, 6577524, 9145645, -6443880),
     369                array(5974874, 3053895, -9433049, -10385191, -31865124, 3225009, -7972642, 3936128, -5652273, -3050304),
     370            ),
     371            array(
     372                array(30625386, -4729400, -25555961, -12792866, -20484575, 7695099, 17097188, -16303496, -27999779, 1803632),
     373                array(-3553091, 9865099, -5228566, 4272701, -5673832, -16689700, 14911344, 12196514, -21405489, 7047412),
     374                array(20093277, 9920966, -11138194, -5343857, 13161587, 12044805, -32856851, 4124601, -32343828, -10257566),
     375            ),
     376            array(
     377                array(-20788824, 14084654, -13531713, 7842147, 19119038, -13822605, 4752377, -8714640, -21679658, 2288038),
     378                array(-26819236, -3283715, 29965059, 3039786, -14473765, 2540457, 29457502, 14625692, -24819617, 12570232),
     379                array(-1063558, -11551823, 16920318, 12494842, 1278292, -5869109, -21159943, -3498680, -11974704, 4724943),
     380            ),
     381            array(
     382                array(17960970, -11775534, -4140968, -9702530, -8876562, -1410617, -12907383, -8659932, -29576300, 1903856),
     383                array(23134274, -14279132, -10681997, -1611936, 20684485, 15770816, -12989750, 3190296, 26955097, 14109738),
     384                array(15308788, 5320727, -30113809, -14318877, 22902008, 7767164, 29425325, -11277562, 31960942, 11934971),
     385            ),
     386            array(
     387                array(-27395711, 8435796, 4109644, 12222639, -24627868, 14818669, 20638173, 4875028, 10491392, 1379718),
     388                array(-13159415, 9197841, 3875503, -8936108, -1383712, -5879801, 33518459, 16176658, 21432314, 12180697),
     389                array(-11787308, 11500838, 13787581, -13832590, -22430679, 10140205, 1465425, 12689540, -10301319, -13872883),
     390            ),
     391        ),
     392        array(
     393            array(
     394                array(5414091, -15386041, -21007664, 9643570, 12834970, 1186149, -2622916, -1342231, 26128231, 6032912),
     395                array(-26337395, -13766162, 32496025, -13653919, 17847801, -12669156, 3604025, 8316894, -25875034, -10437358),
     396                array(3296484, 6223048, 24680646, -12246460, -23052020, 5903205, -8862297, -4639164, 12376617, 3188849),
     397            ),
     398            array(
     399                array(29190488, -14659046, 27549113, -1183516, 3520066, -10697301, 32049515, -7309113, -16109234, -9852307),
     400                array(-14744486, -9309156, 735818, -598978, -20407687, -5057904, 25246078, -15795669, 18640741, -960977),
     401                array(-6928835, -16430795, 10361374, 5642961, 4910474, 12345252, -31638386, -494430, 10530747, 1053335),
     402            ),
     403            array(
     404                array(-29265967, -14186805, -13538216, -12117373, -19457059, -10655384, -31462369, -2948985, 24018831, 15026644),
     405                array(-22592535, -3145277, -2289276, 5953843, -13440189, 9425631, 25310643, 13003497, -2314791, -15145616),
     406                array(-27419985, -603321, -8043984, -1669117, -26092265, 13987819, -27297622, 187899, -23166419, -2531735),
     407            ),
     408            array(
     409                array(-21744398, -13810475, 1844840, 5021428, -10434399, -15911473, 9716667, 16266922, -5070217, 726099),
     410                array(29370922, -6053998, 7334071, -15342259, 9385287, 2247707, -13661962, -4839461, 30007388, -15823341),
     411                array(-936379, 16086691, 23751945, -543318, -1167538, -5189036, 9137109, 730663, 9835848, 4555336),
     412            ),
     413            array(
     414                array(-23376435, 1410446, -22253753, -12899614, 30867635, 15826977, 17693930, 544696, -11985298, 12422646),
     415                array(31117226, -12215734, -13502838, 6561947, -9876867, -12757670, -5118685, -4096706, 29120153, 13924425),
     416                array(-17400879, -14233209, 19675799, -2734756, -11006962, -5858820, -9383939, -11317700, 7240931, -237388),
     417            ),
     418            array(
     419                array(-31361739, -11346780, -15007447, -5856218, -22453340, -12152771, 1222336, 4389483, 3293637, -15551743),
     420                array(-16684801, -14444245, 11038544, 11054958, -13801175, -3338533, -24319580, 7733547, 12796905, -6335822),
     421                array(-8759414, -10817836, -25418864, 10783769, -30615557, -9746811, -28253339, 3647836, 3222231, -11160462),
     422            ),
     423            array(
     424                array(18606113, 1693100, -25448386, -15170272, 4112353, 10045021, 23603893, -2048234, -7550776, 2484985),
     425                array(9255317, -3131197, -12156162, -1004256, 13098013, -9214866, 16377220, -2102812, -19802075, -3034702),
     426                array(-22729289, 7496160, -5742199, 11329249, 19991973, -3347502, -31718148, 9936966, -30097688, -10618797),
     427            ),
     428            array(
     429                array(21878590, -5001297, 4338336, 13643897, -3036865, 13160960, 19708896, 5415497, -7360503, -4109293),
     430                array(27736861, 10103576, 12500508, 8502413, -3413016, -9633558, 10436918, -1550276, -23659143, -8132100),
     431                array(19492550, -12104365, -29681976, -852630, -3208171, 12403437, 30066266, 8367329, 13243957, 8709688),
     432            ),
     433        ),
     434        array(
     435            array(
     436                array(12015105, 2801261, 28198131, 10151021, 24818120, -4743133, -11194191, -5645734, 5150968, 7274186),
     437                array(2831366, -12492146, 1478975, 6122054, 23825128, -12733586, 31097299, 6083058, 31021603, -9793610),
     438                array(-2529932, -2229646, 445613, 10720828, -13849527, -11505937, -23507731, 16354465, 15067285, -14147707),
     439            ),
     440            array(
     441                array(7840942, 14037873, -33364863, 15934016, -728213, -3642706, 21403988, 1057586, -19379462, -12403220),
     442                array(915865, -16469274, 15608285, -8789130, -24357026, 6060030, -17371319, 8410997, -7220461, 16527025),
     443                array(32922597, -556987, 20336074, -16184568, 10903705, -5384487, 16957574, 52992, 23834301, 6588044),
     444            ),
     445            array(
     446                array(32752030, 11232950, 3381995, -8714866, 22652988, -10744103, 17159699, 16689107, -20314580, -1305992),
     447                array(-4689649, 9166776, -25710296, -10847306, 11576752, 12733943, 7924251, -2752281, 1976123, -7249027),
     448                array(21251222, 16309901, -2983015, -6783122, 30810597, 12967303, 156041, -3371252, 12331345, -8237197),
     449            ),
     450            array(
     451                array(8651614, -4477032, -16085636, -4996994, 13002507, 2950805, 29054427, -5106970, 10008136, -4667901),
     452                array(31486080, 15114593, -14261250, 12951354, 14369431, -7387845, 16347321, -13662089, 8684155, -10532952),
     453                array(19443825, 11385320, 24468943, -9659068, -23919258, 2187569, -26263207, -6086921, 31316348, 14219878),
     454            ),
     455            array(
     456                array(-28594490, 1193785, 32245219, 11392485, 31092169, 15722801, 27146014, 6992409, 29126555, 9207390),
     457                array(32382935, 1110093, 18477781, 11028262, -27411763, -7548111, -4980517, 10843782, -7957600, -14435730),
     458                array(2814918, 7836403, 27519878, -7868156, -20894015, -11553689, -21494559, 8550130, 28346258, 1994730),
     459            ),
     460            array(
     461                array(-19578299, 8085545, -14000519, -3948622, 2785838, -16231307, -19516951, 7174894, 22628102, 8115180),
     462                array(-30405132, 955511, -11133838, -15078069, -32447087, -13278079, -25651578, 3317160, -9943017, 930272),
     463                array(-15303681, -6833769, 28856490, 1357446, 23421993, 1057177, 24091212, -1388970, -22765376, -10650715),
     464            ),
     465            array(
     466                array(-22751231, -5303997, -12907607, -12768866, -15811511, -7797053, -14839018, -16554220, -1867018, 8398970),
     467                array(-31969310, 2106403, -4736360, 1362501, 12813763, 16200670, 22981545, -6291273, 18009408, -15772772),
     468                array(-17220923, -9545221, -27784654, 14166835, 29815394, 7444469, 29551787, -3727419, 19288549, 1325865),
     469            ),
     470            array(
     471                array(15100157, -15835752, -23923978, -1005098, -26450192, 15509408, 12376730, -3479146, 33166107, -8042750),
     472                array(20909231, 13023121, -9209752, 16251778, -5778415, -8094914, 12412151, 10018715, 2213263, -13878373),
     473                array(32529814, -11074689, 30361439, -16689753, -9135940, 1513226, 22922121, 6382134, -5766928, 8371348),
     474            ),
     475        ),
     476        array(
     477            array(
     478                array(9923462, 11271500, 12616794, 3544722, -29998368, -1721626, 12891687, -8193132, -26442943, 10486144),
     479                array(-22597207, -7012665, 8587003, -8257861, 4084309, -12970062, 361726, 2610596, -23921530, -11455195),
     480                array(5408411, -1136691, -4969122, 10561668, 24145918, 14240566, 31319731, -4235541, 19985175, -3436086),
     481            ),
     482            array(
     483                array(-13994457, 16616821, 14549246, 3341099, 32155958, 13648976, -17577068, 8849297, 65030, 8370684),
     484                array(-8320926, -12049626, 31204563, 5839400, -20627288, -1057277, -19442942, 6922164, 12743482, -9800518),
     485                array(-2361371, 12678785, 28815050, 4759974, -23893047, 4884717, 23783145, 11038569, 18800704, 255233),
     486            ),
     487            array(
     488                array(-5269658, -1773886, 13957886, 7990715, 23132995, 728773, 13393847, 9066957, 19258688, -14753793),
     489                array(-2936654, -10827535, -10432089, 14516793, -3640786, 4372541, -31934921, 2209390, -1524053, 2055794),
     490                array(580882, 16705327, 5468415, -2683018, -30926419, -14696000, -7203346, -8994389, -30021019, 7394435),
     491            ),
     492            array(
     493                array(23838809, 1822728, -15738443, 15242727, 8318092, -3733104, -21672180, -3492205, -4821741, 14799921),
     494                array(13345610, 9759151, 3371034, -16137791, 16353039, 8577942, 31129804, 13496856, -9056018, 7402518),
     495                array(2286874, -4435931, -20042458, -2008336, -13696227, 5038122, 11006906, -15760352, 8205061, 1607563),
     496            ),
     497            array(
     498                array(14414086, -8002132, 3331830, -3208217, 22249151, -5594188, 18364661, -2906958, 30019587, -9029278),
     499                array(-27688051, 1585953, -10775053, 931069, -29120221, -11002319, -14410829, 12029093, 9944378, 8024),
     500                array(4368715, -3709630, 29874200, -15022983, -20230386, -11410704, -16114594, -999085, -8142388, 5640030),
     501            ),
     502            array(
     503                array(10299610, 13746483, 11661824, 16234854, 7630238, 5998374, 9809887, -16694564, 15219798, -14327783),
     504                array(27425505, -5719081, 3055006, 10660664, 23458024, 595578, -15398605, -1173195, -18342183, 9742717),
     505                array(6744077, 2427284, 26042789, 2720740, -847906, 1118974, 32324614, 7406442, 12420155, 1994844),
     506            ),
     507            array(
     508                array(14012521, -5024720, -18384453, -9578469, -26485342, -3936439, -13033478, -10909803, 24319929, -6446333),
     509                array(16412690, -4507367, 10772641, 15929391, -17068788, -4658621, 10555945, -10484049, -30102368, -4739048),
     510                array(22397382, -7767684, -9293161, -12792868, 17166287, -9755136, -27333065, 6199366, 21880021, -12250760),
     511            ),
     512            array(
     513                array(-4283307, 5368523, -31117018, 8163389, -30323063, 3209128, 16557151, 8890729, 8840445, 4957760),
     514                array(-15447727, 709327, -6919446, -10870178, -29777922, 6522332, -21720181, 12130072, -14796503, 5005757),
     515                array(-2114751, -14308128, 23019042, 15765735, -25269683, 6002752, 10183197, -13239326, -16395286, -2176112),
     516            ),
     517        ),
     518        array(
     519            array(
     520                array(-19025756, 1632005, 13466291, -7995100, -23640451, 16573537, -32013908, -3057104, 22208662, 2000468),
     521                array(3065073, -1412761, -25598674, -361432, -17683065, -5703415, -8164212, 11248527, -3691214, -7414184),
     522                array(10379208, -6045554, 8877319, 1473647, -29291284, -12507580, 16690915, 2553332, -3132688, 16400289),
     523            ),
     524            array(
     525                array(15716668, 1254266, -18472690, 7446274, -8448918, 6344164, -22097271, -7285580, 26894937, 9132066),
     526                array(24158887, 12938817, 11085297, -8177598, -28063478, -4457083, -30576463, 64452, -6817084, -2692882),
     527                array(13488534, 7794716, 22236231, 5989356, 25426474, -12578208, 2350710, -3418511, -4688006, 2364226),
     528            ),
     529            array(
     530                array(16335052, 9132434, 25640582, 6678888, 1725628, 8517937, -11807024, -11697457, 15445875, -7798101),
     531                array(29004207, -7867081, 28661402, -640412, -12794003, -7943086, 31863255, -4135540, -278050, -15759279),
     532                array(-6122061, -14866665, -28614905, 14569919, -10857999, -3591829, 10343412, -6976290, -29828287, -10815811),
     533            ),
     534            array(
     535                array(27081650, 3463984, 14099042, -4517604, 1616303, -6205604, 29542636, 15372179, 17293797, 960709),
     536                array(20263915, 11434237, -5765435, 11236810, 13505955, -10857102, -16111345, 6493122, -19384511, 7639714),
     537                array(-2830798, -14839232, 25403038, -8215196, -8317012, -16173699, 18006287, -16043750, 29994677, -15808121),
     538            ),
     539            array(
     540                array(9769828, 5202651, -24157398, -13631392, -28051003, -11561624, -24613141, -13860782, -31184575, 709464),
     541                array(12286395, 13076066, -21775189, -1176622, -25003198, 4057652, -32018128, -8890874, 16102007, 13205847),
     542                array(13733362, 5599946, 10557076, 3195751, -5557991, 8536970, -25540170, 8525972, 10151379, 10394400),
     543            ),
     544            array(
     545                array(4024660, -16137551, 22436262, 12276534, -9099015, -2686099, 19698229, 11743039, -33302334, 8934414),
     546                array(-15879800, -4525240, -8580747, -2934061, 14634845, -698278, -9449077, 3137094, -11536886, 11721158),
     547                array(17555939, -5013938, 8268606, 2331751, -22738815, 9761013, 9319229, 8835153, -9205489, -1280045),
     548            ),
     549            array(
     550                array(-461409, -7830014, 20614118, 16688288, -7514766, -4807119, 22300304, 505429, 6108462, -6183415),
     551                array(-5070281, 12367917, -30663534, 3234473, 32617080, -8422642, 29880583, -13483331, -26898490, -7867459),
     552                array(-31975283, 5726539, 26934134, 10237677, -3173717, -605053, 24199304, 3795095, 7592688, -14992079),
     553            ),
     554            array(
     555                array(21594432, -14964228, 17466408, -4077222, 32537084, 2739898, 6407723, 12018833, -28256052, 4298412),
     556                array(-20650503, -11961496, -27236275, 570498, 3767144, -1717540, 13891942, -1569194, 13717174, 10805743),
     557                array(-14676630, -15644296, 15287174, 11927123, 24177847, -8175568, -796431, 14860609, -26938930, -5863836),
     558            ),
     559        ),
     560        array(
     561            array(
     562                array(12962541, 5311799, -10060768, 11658280, 18855286, -7954201, 13286263, -12808704, -4381056, 9882022),
     563                array(18512079, 11319350, -20123124, 15090309, 18818594, 5271736, -22727904, 3666879, -23967430, -3299429),
     564                array(-6789020, -3146043, 16192429, 13241070, 15898607, -14206114, -10084880, -6661110, -2403099, 5276065),
     565            ),
     566            array(
     567                array(30169808, -5317648, 26306206, -11750859, 27814964, 7069267, 7152851, 3684982, 1449224, 13082861),
     568                array(10342826, 3098505, 2119311, 193222, 25702612, 12233820, 23697382, 15056736, -21016438, -8202000),
     569                array(-33150110, 3261608, 22745853, 7948688, 19370557, -15177665, -26171976, 6482814, -10300080, -11060101),
     570            ),
     571            array(
     572                array(32869458, -5408545, 25609743, 15678670, -10687769, -15471071, 26112421, 2521008, -22664288, 6904815),
     573                array(29506923, 4457497, 3377935, -9796444, -30510046, 12935080, 1561737, 3841096, -29003639, -6657642),
     574                array(10340844, -6630377, -18656632, -2278430, 12621151, -13339055, 30878497, -11824370, -25584551, 5181966),
     575            ),
     576            array(
     577                array(25940115, -12658025, 17324188, -10307374, -8671468, 15029094, 24396252, -16450922, -2322852, -12388574),
     578                array(-21765684, 9916823, -1300409, 4079498, -1028346, 11909559, 1782390, 12641087, 20603771, -6561742),
     579                array(-18882287, -11673380, 24849422, 11501709, 13161720, -4768874, 1925523, 11914390, 4662781, 7820689),
     580            ),
     581            array(
     582                array(12241050, -425982, 8132691, 9393934, 32846760, -1599620, 29749456, 12172924, 16136752, 15264020),
     583                array(-10349955, -14680563, -8211979, 2330220, -17662549, -14545780, 10658213, 6671822, 19012087, 3772772),
     584                array(3753511, -3421066, 10617074, 2028709, 14841030, -6721664, 28718732, -15762884, 20527771, 12988982),
     585            ),
     586            array(
     587                array(-14822485, -5797269, -3707987, 12689773, -898983, -10914866, -24183046, -10564943, 3299665, -12424953),
     588                array(-16777703, -15253301, -9642417, 4978983, 3308785, 8755439, 6943197, 6461331, -25583147, 8991218),
     589                array(-17226263, 1816362, -1673288, -6086439, 31783888, -8175991, -32948145, 7417950, -30242287, 1507265),
     590            ),
     591            array(
     592                array(29692663, 6829891, -10498800, 4334896, 20945975, -11906496, -28887608, 8209391, 14606362, -10647073),
     593                array(-3481570, 8707081, 32188102, 5672294, 22096700, 1711240, -33020695, 9761487, 4170404, -2085325),
     594                array(-11587470, 14855945, -4127778, -1531857, -26649089, 15084046, 22186522, 16002000, -14276837, -8400798),
     595            ),
     596            array(
     597                array(-4811456, 13761029, -31703877, -2483919, -3312471, 7869047, -7113572, -9620092, 13240845, 10965870),
     598                array(-7742563, -8256762, -14768334, -13656260, -23232383, 12387166, 4498947, 14147411, 29514390, 4302863),
     599                array(-13413405, -12407859, 20757302, -13801832, 14785143, 8976368, -5061276, -2144373, 17846988, -13971927),
     600            ),
     601        ),
     602        array(
     603            array(
     604                array(-2244452, -754728, -4597030, -1066309, -6247172, 1455299, -21647728, -9214789, -5222701, 12650267),
     605                array(-9906797, -16070310, 21134160, 12198166, -27064575, 708126, 387813, 13770293, -19134326, 10958663),
     606                array(22470984, 12369526, 23446014, -5441109, -21520802, -9698723, -11772496, -11574455, -25083830, 4271862),
     607            ),
     608            array(
     609                array(-25169565, -10053642, -19909332, 15361595, -5984358, 2159192, 75375, -4278529, -32526221, 8469673),
     610                array(15854970, 4148314, -8893890, 7259002, 11666551, 13824734, -30531198, 2697372, 24154791, -9460943),
     611                array(15446137, -15806644, 29759747, 14019369, 30811221, -9610191, -31582008, 12840104, 24913809, 9815020),
     612            ),
     613            array(
     614                array(-4709286, -5614269, -31841498, -12288893, -14443537, 10799414, -9103676, 13438769, 18735128, 9466238),
     615                array(11933045, 9281483, 5081055, -5183824, -2628162, -4905629, -7727821, -10896103, -22728655, 16199064),
     616                array(14576810, 379472, -26786533, -8317236, -29426508, -10812974, -102766, 1876699, 30801119, 2164795),
     617            ),
     618            array(
     619                array(15995086, 3199873, 13672555, 13712240, -19378835, -4647646, -13081610, -15496269, -13492807, 1268052),
     620                array(-10290614, -3659039, -3286592, 10948818, 23037027, 3794475, -3470338, -12600221, -17055369, 3565904),
     621                array(29210088, -9419337, -5919792, -4952785, 10834811, -13327726, -16512102, -10820713, -27162222, -14030531),
     622            ),
     623            array(
     624                array(-13161890, 15508588, 16663704, -8156150, -28349942, 9019123, -29183421, -3769423, 2244111, -14001979),
     625                array(-5152875, -3800936, -9306475, -6071583, 16243069, 14684434, -25673088, -16180800, 13491506, 4641841),
     626                array(10813417, 643330, -19188515, -728916, 30292062, -16600078, 27548447, -7721242, 14476989, -12767431),
     627            ),
     628            array(
     629                array(10292079, 9984945, 6481436, 8279905, -7251514, 7032743, 27282937, -1644259, -27912810, 12651324),
     630                array(-31185513, -813383, 22271204, 11835308, 10201545, 15351028, 17099662, 3988035, 21721536, -3148940),
     631                array(10202177, -6545839, -31373232, -9574638, -32150642, -8119683, -12906320, 3852694, 13216206, 14842320),
     632            ),
     633            array(
     634                array(-15815640, -10601066, -6538952, -7258995, -6984659, -6581778, -31500847, 13765824, -27434397, 9900184),
     635                array(14465505, -13833331, -32133984, -14738873, -27443187, 12990492, 33046193, 15796406, -7051866, -8040114),
     636                array(30924417, -8279620, 6359016, -12816335, 16508377, 9071735, -25488601, 15413635, 9524356, -7018878),
     637            ),
     638            array(
     639                array(12274201, -13175547, 32627641, -1785326, 6736625, 13267305, 5237659, -5109483, 15663516, 4035784),
     640                array(-2951309, 8903985, 17349946, 601635, -16432815, -4612556, -13732739, -15889334, -22258478, 4659091),
     641                array(-16916263, -4952973, -30393711, -15158821, 20774812, 15897498, 5736189, 15026997, -2178256, -13455585),
     642            ),
     643        ),
     644        array(
     645            array(
     646                array(-8858980, -2219056, 28571666, -10155518, -474467, -10105698, -3801496, 278095, 23440562, -290208),
     647                array(10226241, -5928702, 15139956, 120818, -14867693, 5218603, 32937275, 11551483, -16571960, -7442864),
     648                array(17932739, -12437276, -24039557, 10749060, 11316803, 7535897, 22503767, 5561594, -3646624, 3898661),
     649            ),
     650            array(
     651                array(7749907, -969567, -16339731, -16464, -25018111, 15122143, -1573531, 7152530, 21831162, 1245233),
     652                array(26958459, -14658026, 4314586, 8346991, -5677764, 11960072, -32589295, -620035, -30402091, -16716212),
     653                array(-12165896, 9166947, 33491384, 13673479, 29787085, 13096535, 6280834, 14587357, -22338025, 13987525),
     654            ),
     655            array(
     656                array(-24349909, 7778775, 21116000, 15572597, -4833266, -5357778, -4300898, -5124639, -7469781, -2858068),
     657                array(9681908, -6737123, -31951644, 13591838, -6883821, 386950, 31622781, 6439245, -14581012, 4091397),
     658                array(-8426427, 1470727, -28109679, -1596990, 3978627, -5123623, -19622683, 12092163, 29077877, -14741988),
     659            ),
     660            array(
     661                array(5269168, -6859726, -13230211, -8020715, 25932563, 1763552, -5606110, -5505881, -20017847, 2357889),
     662                array(32264008, -15407652, -5387735, -1160093, -2091322, -3946900, 23104804, -12869908, 5727338, 189038),
     663                array(14609123, -8954470, -6000566, -16622781, -14577387, -7743898, -26745169, 10942115, -25888931, -14884697),
     664            ),
     665            array(
     666                array(20513500, 5557931, -15604613, 7829531, 26413943, -2019404, -21378968, 7471781, 13913677, -5137875),
     667                array(-25574376, 11967826, 29233242, 12948236, -6754465, 4713227, -8940970, 14059180, 12878652, 8511905),
     668                array(-25656801, 3393631, -2955415, -7075526, -2250709, 9366908, -30223418, 6812974, 5568676, -3127656),
     669            ),
     670            array(
     671                array(11630004, 12144454, 2116339, 13606037, 27378885, 15676917, -17408753, -13504373, -14395196, 8070818),
     672                array(27117696, -10007378, -31282771, -5570088, 1127282, 12772488, -29845906, 10483306, -11552749, -1028714),
     673                array(10637467, -5688064, 5674781, 1072708, -26343588, -6982302, -1683975, 9177853, -27493162, 15431203),
     674            ),
     675            array(
     676                array(20525145, 10892566, -12742472, 12779443, -29493034, 16150075, -28240519, 14943142, -15056790, -7935931),
     677                array(-30024462, 5626926, -551567, -9981087, 753598, 11981191, 25244767, -3239766, -3356550, 9594024),
     678                array(-23752644, 2636870, -5163910, -10103818, 585134, 7877383, 11345683, -6492290, 13352335, -10977084),
     679            ),
     680            array(
     681                array(-1931799, -5407458, 3304649, -12884869, 17015806, -4877091, -29783850, -7752482, -13215537, -319204),
     682                array(20239939, 6607058, 6203985, 3483793, -18386976, -779229, -20723742, 15077870, -22750759, 14523817),
     683                array(27406042, -6041657, 27423596, -4497394, 4996214, 10002360, -28842031, -4545494, -30172742, -4805667),
     684            ),
     685        ),
     686        array(
     687            array(
     688                array(11374242, 12660715, 17861383, -12540833, 10935568, 1099227, -13886076, -9091740, -27727044, 11358504),
     689                array(-12730809, 10311867, 1510375, 10778093, -2119455, -9145702, 32676003, 11149336, -26123651, 4985768),
     690                array(-19096303, 341147, -6197485, -239033, 15756973, -8796662, -983043, 13794114, -19414307, -15621255),
     691            ),
     692            array(
     693                array(6490081, 11940286, 25495923, -7726360, 8668373, -8751316, 3367603, 6970005, -1691065, -9004790),
     694                array(1656497, 13457317, 15370807, 6364910, 13605745, 8362338, -19174622, -5475723, -16796596, -5031438),
     695                array(-22273315, -13524424, -64685, -4334223, -18605636, -10921968, -20571065, -7007978, -99853, -10237333),
     696            ),
     697            array(
     698                array(17747465, 10039260, 19368299, -4050591, -20630635, -16041286, 31992683, -15857976, -29260363, -5511971),
     699                array(31932027, -4986141, -19612382, 16366580, 22023614, 88450, 11371999, -3744247, 4882242, -10626905),
     700                array(29796507, 37186, 19818052, 10115756, -11829032, 3352736, 18551198, 3272828, -5190932, -4162409),
     701            ),
     702            array(
     703                array(12501286, 4044383, -8612957, -13392385, -32430052, 5136599, -19230378, -3529697, 330070, -3659409),
     704                array(6384877, 2899513, 17807477, 7663917, -2358888, 12363165, 25366522, -8573892, -271295, 12071499),
     705                array(-8365515, -4042521, 25133448, -4517355, -6211027, 2265927, -32769618, 1936675, -5159697, 3829363),
     706            ),
     707            array(
     708                array(28425966, -5835433, -577090, -4697198, -14217555, 6870930, 7921550, -6567787, 26333140, 14267664),
     709                array(-11067219, 11871231, 27385719, -10559544, -4585914, -11189312, 10004786, -8709488, -21761224, 8930324),
     710                array(-21197785, -16396035, 25654216, -1725397, 12282012, 11008919, 1541940, 4757911, -26491501, -16408940),
     711            ),
     712            array(
     713                array(13537262, -7759490, -20604840, 10961927, -5922820, -13218065, -13156584, 6217254, -15943699, 13814990),
     714                array(-17422573, 15157790, 18705543, 29619, 24409717, -260476, 27361681, 9257833, -1956526, -1776914),
     715                array(-25045300, -10191966, 15366585, 15166509, -13105086, 8423556, -29171540, 12361135, -18685978, 4578290),
     716            ),
     717            array(
     718                array(24579768, 3711570, 1342322, -11180126, -27005135, 14124956, -22544529, 14074919, 21964432, 8235257),
     719                array(-6528613, -2411497, 9442966, -5925588, 12025640, -1487420, -2981514, -1669206, 13006806, 2355433),
     720                array(-16304899, -13605259, -6632427, -5142349, 16974359, -10911083, 27202044, 1719366, 1141648, -12796236),
     721            ),
     722            array(
     723                array(-12863944, -13219986, -8318266, -11018091, -6810145, -4843894, 13475066, -3133972, 32674895, 13715045),
     724                array(11423335, -5468059, 32344216, 8962751, 24989809, 9241752, -13265253, 16086212, -28740881, -15642093),
     725                array(-1409668, 12530728, -6368726, 10847387, 19531186, -14132160, -11709148, 7791794, -27245943, 4383347),
     726            ),
     727        ),
     728        array(
     729            array(
     730                array(-28970898, 5271447, -1266009, -9736989, -12455236, 16732599, -4862407, -4906449, 27193557, 6245191),
     731                array(-15193956, 5362278, -1783893, 2695834, 4960227, 12840725, 23061898, 3260492, 22510453, 8577507),
     732                array(-12632451, 11257346, -32692994, 13548177, -721004, 10879011, 31168030, 13952092, -29571492, -3635906),
     733            ),
     734            array(
     735                array(3877321, -9572739, 32416692, 5405324, -11004407, -13656635, 3759769, 11935320, 5611860, 8164018),
     736                array(-16275802, 14667797, 15906460, 12155291, -22111149, -9039718, 32003002, -8832289, 5773085, -8422109),
     737                array(-23788118, -8254300, 1950875, 8937633, 18686727, 16459170, -905725, 12376320, 31632953, 190926),
     738            ),
     739            array(
     740                array(-24593607, -16138885, -8423991, 13378746, 14162407, 6901328, -8288749, 4508564, -25341555, -3627528),
     741                array(8884438, -5884009, 6023974, 10104341, -6881569, -4941533, 18722941, -14786005, -1672488, 827625),
     742                array(-32720583, -16289296, -32503547, 7101210, 13354605, 2659080, -1800575, -14108036, -24878478, 1541286),
     743            ),
     744            array(
     745                array(2901347, -1117687, 3880376, -10059388, -17620940, -3612781, -21802117, -3567481, 20456845, -1885033),
     746                array(27019610, 12299467, -13658288, -1603234, -12861660, -4861471, -19540150, -5016058, 29439641, 15138866),
     747                array(21536104, -6626420, -32447818, -10690208, -22408077, 5175814, -5420040, -16361163, 7779328, 109896),
     748            ),
     749            array(
     750                array(30279744, 14648750, -8044871, 6425558, 13639621, -743509, 28698390, 12180118, 23177719, -554075),
     751                array(26572847, 3405927, -31701700, 12890905, -19265668, 5335866, -6493768, 2378492, 4439158, -13279347),
     752                array(-22716706, 3489070, -9225266, -332753, 18875722, -1140095, 14819434, -12731527, -17717757, -5461437),
     753            ),
     754            array(
     755                array(-5056483, 16566551, 15953661, 3767752, -10436499, 15627060, -820954, 2177225, 8550082, -15114165),
     756                array(-18473302, 16596775, -381660, 15663611, 22860960, 15585581, -27844109, -3582739, -23260460, -8428588),
     757                array(-32480551, 15707275, -8205912, -5652081, 29464558, 2713815, -22725137, 15860482, -21902570, 1494193),
     758            ),
     759            array(
     760                array(-19562091, -14087393, -25583872, -9299552, 13127842, 759709, 21923482, 16529112, 8742704, 12967017),
     761                array(-28464899, 1553205, 32536856, -10473729, -24691605, -406174, -8914625, -2933896, -29903758, 15553883),
     762                array(21877909, 3230008, 9881174, 10539357, -4797115, 2841332, 11543572, 14513274, 19375923, -12647961),
     763            ),
     764            array(
     765                array(8832269, -14495485, 13253511, 5137575, 5037871, 4078777, 24880818, -6222716, 2862653, 9455043),
     766                array(29306751, 5123106, 20245049, -14149889, 9592566, 8447059, -2077124, -2990080, 15511449, 4789663),
     767                array(-20679756, 7004547, 8824831, -9434977, -4045704, -3750736, -5754762, 108893, 23513200, 16652362),
     768            ),
     769        ),
     770        array(
     771            array(
     772                array(-33256173, 4144782, -4476029, -6579123, 10770039, -7155542, -6650416, -12936300, -18319198, 10212860),
     773                array(2756081, 8598110, 7383731, -6859892, 22312759, -1105012, 21179801, 2600940, -9988298, -12506466),
     774                array(-24645692, 13317462, -30449259, -15653928, 21365574, -10869657, 11344424, 864440, -2499677, -16710063),
     775            ),
     776            array(
     777                array(-26432803, 6148329, -17184412, -14474154, 18782929, -275997, -22561534, 211300, 2719757, 4940997),
     778                array(-1323882, 3911313, -6948744, 14759765, -30027150, 7851207, 21690126, 8518463, 26699843, 5276295),
     779                array(-13149873, -6429067, 9396249, 365013, 24703301, -10488939, 1321586, 149635, -15452774, 7159369),
     780            ),
     781            array(
     782                array(9987780, -3404759, 17507962, 9505530, 9731535, -2165514, 22356009, 8312176, 22477218, -8403385),
     783                array(18155857, -16504990, 19744716, 9006923, 15154154, -10538976, 24256460, -4864995, -22548173, 9334109),
     784                array(2986088, -4911893, 10776628, -3473844, 10620590, -7083203, -21413845, 14253545, -22587149, 536906),
     785            ),
     786            array(
     787                array(4377756, 8115836, 24567078, 15495314, 11625074, 13064599, 7390551, 10589625, 10838060, -15420424),
     788                array(-19342404, 867880, 9277171, -3218459, -14431572, -1986443, 19295826, -15796950, 6378260, 699185),
     789                array(7895026, 4057113, -7081772, -13077756, -17886831, -323126, -716039, 15693155, -5045064, -13373962),
     790            ),
     791            array(
     792                array(-7737563, -5869402, -14566319, -7406919, 11385654, 13201616, 31730678, -10962840, -3918636, -9669325),
     793                array(10188286, -15770834, -7336361, 13427543, 22223443, 14896287, 30743455, 7116568, -21786507, 5427593),
     794                array(696102, 13206899, 27047647, -10632082, 15285305, -9853179, 10798490, -4578720, 19236243, 12477404),
     795            ),
     796            array(
     797                array(-11229439, 11243796, -17054270, -8040865, -788228, -8167967, -3897669, 11180504, -23169516, 7733644),
     798                array(17800790, -14036179, -27000429, -11766671, 23887827, 3149671, 23466177, -10538171, 10322027, 15313801),
     799                array(26246234, 11968874, 32263343, -5468728, 6830755, -13323031, -15794704, -101982, -24449242, 10890804),
     800            ),
     801            array(
     802                array(-31365647, 10271363, -12660625, -6267268, 16690207, -13062544, -14982212, 16484931, 25180797, -5334884),
     803                array(-586574, 10376444, -32586414, -11286356, 19801893, 10997610, 2276632, 9482883, 316878, 13820577),
     804                array(-9882808, -4510367, -2115506, 16457136, -11100081, 11674996, 30756178, -7515054, 30696930, -3712849),
     805            ),
     806            array(
     807                array(32988917, -9603412, 12499366, 7910787, -10617257, -11931514, -7342816, -9985397, -32349517, 7392473),
     808                array(-8855661, 15927861, 9866406, -3649411, -2396914, -16655781, -30409476, -9134995, 25112947, -2926644),
     809                array(-2504044, -436966, 25621774, -5678772, 15085042, -5479877, -24884878, -13526194, 5537438, -13914319),
     810            ),
     811        ),
     812        array(
     813            array(
     814                array(-11225584, 2320285, -9584280, 10149187, -33444663, 5808648, -14876251, -1729667, 31234590, 6090599),
     815                array(-9633316, 116426, 26083934, 2897444, -6364437, -2688086, 609721, 15878753, -6970405, -9034768),
     816                array(-27757857, 247744, -15194774, -9002551, 23288161, -10011936, -23869595, 6503646, 20650474, 1804084),
     817            ),
     818            array(
     819                array(-27589786, 15456424, 8972517, 8469608, 15640622, 4439847, 3121995, -10329713, 27842616, -202328),
     820                array(-15306973, 2839644, 22530074, 10026331, 4602058, 5048462, 28248656, 5031932, -11375082, 12714369),
     821                array(20807691, -7270825, 29286141, 11421711, -27876523, -13868230, -21227475, 1035546, -19733229, 12796920),
     822            ),
     823            array(
     824                array(12076899, -14301286, -8785001, -11848922, -25012791, 16400684, -17591495, -12899438, 3480665, -15182815),
     825                array(-32361549, 5457597, 28548107, 7833186, 7303070, -11953545, -24363064, -15921875, -33374054, 2771025),
     826                array(-21389266, 421932, 26597266, 6860826, 22486084, -6737172, -17137485, -4210226, -24552282, 15673397),
     827            ),
     828            array(
     829                array(-20184622, 2338216, 19788685, -9620956, -4001265, -8740893, -20271184, 4733254, 3727144, -12934448),
     830                array(6120119, 814863, -11794402, -622716, 6812205, -15747771, 2019594, 7975683, 31123697, -10958981),
     831                array(30069250, -11435332, 30434654, 2958439, 18399564, -976289, 12296869, 9204260, -16432438, 9648165),
     832            ),
     833            array(
     834                array(32705432, -1550977, 30705658, 7451065, -11805606, 9631813, 3305266, 5248604, -26008332, -11377501),
     835                array(17219865, 2375039, -31570947, -5575615, -19459679, 9219903, 294711, 15298639, 2662509, -16297073),
     836                array(-1172927, -7558695, -4366770, -4287744, -21346413, -8434326, 32087529, -1222777, 32247248, -14389861),
     837            ),
     838            array(
     839                array(14312628, 1221556, 17395390, -8700143, -4945741, -8684635, -28197744, -9637817, -16027623, -13378845),
     840                array(-1428825, -9678990, -9235681, 6549687, -7383069, -468664, 23046502, 9803137, 17597934, 2346211),
     841                array(18510800, 15337574, 26171504, 981392, -22241552, 7827556, -23491134, -11323352, 3059833, -11782870),
     842            ),
     843            array(
     844                array(10141598, 6082907, 17829293, -1947643, 9830092, 13613136, -25556636, -5544586, -33502212, 3592096),
     845                array(33114168, -15889352, -26525686, -13343397, 33076705, 8716171, 1151462, 1521897, -982665, -6837803),
     846                array(-32939165, -4255815, 23947181, -324178, -33072974, -12305637, -16637686, 3891704, 26353178, 693168),
     847            ),
     848            array(
     849                array(30374239, 1595580, -16884039, 13186931, 4600344, 406904, 9585294, -400668, 31375464, 14369965),
     850                array(-14370654, -7772529, 1510301, 6434173, -18784789, -6262728, 32732230, -13108839, 17901441, 16011505),
     851                array(18171223, -11934626, -12500402, 15197122, -11038147, -15230035, -19172240, -16046376, 8764035, 12309598),
     852            ),
     853        ),
     854        array(
     855            array(
     856                array(5975908, -5243188, -19459362, -9681747, -11541277, 14015782, -23665757, 1228319, 17544096, -10593782),
     857                array(5811932, -1715293, 3442887, -2269310, -18367348, -8359541, -18044043, -15410127, -5565381, 12348900),
     858                array(-31399660, 11407555, 25755363, 6891399, -3256938, 14872274, -24849353, 8141295, -10632534, -585479),
     859            ),
     860            array(
     861                array(-12675304, 694026, -5076145, 13300344, 14015258, -14451394, -9698672, -11329050, 30944593, 1130208),
     862                array(8247766, -6710942, -26562381, -7709309, -14401939, -14648910, 4652152, 2488540, 23550156, -271232),
     863                array(17294316, -3788438, 7026748, 15626851, 22990044, 113481, 2267737, -5908146, -408818, -137719),
     864            ),
     865            array(
     866                array(16091085, -16253926, 18599252, 7340678, 2137637, -1221657, -3364161, 14550936, 3260525, -7166271),
     867                array(-4910104, -13332887, 18550887, 10864893, -16459325, -7291596, -23028869, -13204905, -12748722, 2701326),
     868                array(-8574695, 16099415, 4629974, -16340524, -20786213, -6005432, -10018363, 9276971, 11329923, 1862132),
     869            ),
     870            array(
     871                array(14763076, -15903608, -30918270, 3689867, 3511892, 10313526, -21951088, 12219231, -9037963, -940300),
     872                array(8894987, -3446094, 6150753, 3013931, 301220, 15693451, -31981216, -2909717, -15438168, 11595570),
     873                array(15214962, 3537601, -26238722, -14058872, 4418657, -15230761, 13947276, 10730794, -13489462, -4363670),
     874            ),
     875            array(
     876                array(-2538306, 7682793, 32759013, 263109, -29984731, -7955452, -22332124, -10188635, 977108, 699994),
     877                array(-12466472, 4195084, -9211532, 550904, -15565337, 12917920, 19118110, -439841, -30534533, -14337913),
     878                array(31788461, -14507657, 4799989, 7372237, 8808585, -14747943, 9408237, -10051775, 12493932, -5409317),
     879            ),
     880            array(
     881                array(-25680606, 5260744, -19235809, -6284470, -3695942, 16566087, 27218280, 2607121, 29375955, 6024730),
     882                array(842132, -2794693, -4763381, -8722815, 26332018, -12405641, 11831880, 6985184, -9940361, 2854096),
     883                array(-4847262, -7969331, 2516242, -5847713, 9695691, -7221186, 16512645, 960770, 12121869, 16648078),
     884            ),
     885            array(
     886                array(-15218652, 14667096, -13336229, 2013717, 30598287, -464137, -31504922, -7882064, 20237806, 2838411),
     887                array(-19288047, 4453152, 15298546, -16178388, 22115043, -15972604, 12544294, -13470457, 1068881, -12499905),
     888                array(-9558883, -16518835, 33238498, 13506958, 30505848, -1114596, -8486907, -2630053, 12521378, 4845654),
     889            ),
     890            array(
     891                array(-28198521, 10744108, -2958380, 10199664, 7759311, -13088600, 3409348, -873400, -6482306, -12885870),
     892                array(-23561822, 6230156, -20382013, 10655314, -24040585, -11621172, 10477734, -1240216, -3113227, 13974498),
     893                array(12966261, 15550616, -32038948, -1615346, 21025980, -629444, 5642325, 7188737, 18895762, 12629579),
     894            ),
     895        ),
     896        array(
     897            array(
     898                array(14741879, -14946887, 22177208, -11721237, 1279741, 8058600, 11758140, 789443, 32195181, 3895677),
     899                array(10758205, 15755439, -4509950, 9243698, -4879422, 6879879, -2204575, -3566119, -8982069, 4429647),
     900                array(-2453894, 15725973, -20436342, -10410672, -5803908, -11040220, -7135870, -11642895, 18047436, -15281743),
     901            ),
     902            array(
     903                array(-25173001, -11307165, 29759956, 11776784, -22262383, -15820455, 10993114, -12850837, -17620701, -9408468),
     904                array(21987233, 700364, -24505048, 14972008, -7774265, -5718395, 32155026, 2581431, -29958985, 8773375),
     905                array(-25568350, 454463, -13211935, 16126715, 25240068, 8594567, 20656846, 12017935, -7874389, -13920155),
     906            ),
     907            array(
     908                array(6028182, 6263078, -31011806, -11301710, -818919, 2461772, -31841174, -5468042, -1721788, -2776725),
     909                array(-12278994, 16624277, 987579, -5922598, 32908203, 1248608, 7719845, -4166698, 28408820, 6816612),
     910                array(-10358094, -8237829, 19549651, -12169222, 22082623, 16147817, 20613181, 13982702, -10339570, 5067943),
     911            ),
     912            array(
     913                array(-30505967, -3821767, 12074681, 13582412, -19877972, 2443951, -19719286, 12746132, 5331210, -10105944),
     914                array(30528811, 3601899, -1957090, 4619785, -27361822, -15436388, 24180793, -12570394, 27679908, -1648928),
     915                array(9402404, -13957065, 32834043, 10838634, -26580150, -13237195, 26653274, -8685565, 22611444, -12715406),
     916            ),
     917            array(
     918                array(22190590, 1118029, 22736441, 15130463, -30460692, -5991321, 19189625, -4648942, 4854859, 6622139),
     919                array(-8310738, -2953450, -8262579, -3388049, -10401731, -271929, 13424426, -3567227, 26404409, 13001963),
     920                array(-31241838, -15415700, -2994250, 8939346, 11562230, -12840670, -26064365, -11621720, -15405155, 11020693),
     921            ),
     922            array(
     923                array(1866042, -7949489, -7898649, -10301010, 12483315, 13477547, 3175636, -12424163, 28761762, 1406734),
     924                array(-448555, -1777666, 13018551, 3194501, -9580420, -11161737, 24760585, -4347088, 25577411, -13378680),
     925                array(-24290378, 4759345, -690653, -1852816, 2066747, 10693769, -29595790, 9884936, -9368926, 4745410),
     926            ),
     927            array(
     928                array(-9141284, 6049714, -19531061, -4341411, -31260798, 9944276, -15462008, -11311852, 10931924, -11931931),
     929                array(-16561513, 14112680, -8012645, 4817318, -8040464, -11414606, -22853429, 10856641, -20470770, 13434654),
     930                array(22759489, -10073434, -16766264, -1871422, 13637442, -10168091, 1765144, -12654326, 28445307, -5364710),
     931            ),
     932            array(
     933                array(29875063, 12493613, 2795536, -3786330, 1710620, 15181182, -10195717, -8788675, 9074234, 1167180),
     934                array(-26205683, 11014233, -9842651, -2635485, -26908120, 7532294, -18716888, -9535498, 3843903, 9367684),
     935                array(-10969595, -6403711, 9591134, 9582310, 11349256, 108879, 16235123, 8601684, -139197, 4242895),
     936            ),
     937        ),
     938        array(
     939            array(
     940                array(22092954, -13191123, -2042793, -11968512, 32186753, -11517388, -6574341, 2470660, -27417366, 16625501),
     941                array(-11057722, 3042016, 13770083, -9257922, 584236, -544855, -7770857, 2602725, -27351616, 14247413),
     942                array(6314175, -10264892, -32772502, 15957557, -10157730, 168750, -8618807, 14290061, 27108877, -1180880),
     943            ),
     944            array(
     945                array(-8586597, -7170966, 13241782, 10960156, -32991015, -13794596, 33547976, -11058889, -27148451, 981874),
     946                array(22833440, 9293594, -32649448, -13618667, -9136966, 14756819, -22928859, -13970780, -10479804, -16197962),
     947                array(-7768587, 3326786, -28111797, 10783824, 19178761, 14905060, 22680049, 13906969, -15933690, 3797899),
     948            ),
     949            array(
     950                array(21721356, -4212746, -12206123, 9310182, -3882239, -13653110, 23740224, -2709232, 20491983, -8042152),
     951                array(9209270, -15135055, -13256557, -6167798, -731016, 15289673, 25947805, 15286587, 30997318, -6703063),
     952                array(7392032, 16618386, 23946583, -8039892, -13265164, -1533858, -14197445, -2321576, 17649998, -250080),
     953            ),
     954            array(
     955                array(-9301088, -14193827, 30609526, -3049543, -25175069, -1283752, -15241566, -9525724, -2233253, 7662146),
     956                array(-17558673, 1763594, -33114336, 15908610, -30040870, -12174295, 7335080, -8472199, -3174674, 3440183),
     957                array(-19889700, -5977008, -24111293, -9688870, 10799743, -16571957, 40450, -4431835, 4862400, 1133),
     958            ),
     959            array(
     960                array(-32856209, -7873957, -5422389, 14860950, -16319031, 7956142, 7258061, 311861, -30594991, -7379421),
     961                array(-3773428, -1565936, 28985340, 7499440, 24445838, 9325937, 29727763, 16527196, 18278453, 15405622),
     962                array(-4381906, 8508652, -19898366, -3674424, -5984453, 15149970, -13313598, 843523, -21875062, 13626197),
     963            ),
     964            array(
     965                array(2281448, -13487055, -10915418, -2609910, 1879358, 16164207, -10783882, 3953792, 13340839, 15928663),
     966                array(31727126, -7179855, -18437503, -8283652, 2875793, -16390330, -25269894, -7014826, -23452306, 5964753),
     967                array(4100420, -5959452, -17179337, 6017714, -18705837, 12227141, -26684835, 11344144, 2538215, -7570755),
     968            ),
     969            array(
     970                array(-9433605, 6123113, 11159803, -2156608, 30016280, 14966241, -20474983, 1485421, -629256, -15958862),
     971                array(-26804558, 4260919, 11851389, 9658551, -32017107, 16367492, -20205425, -13191288, 11659922, -11115118),
     972                array(26180396, 10015009, -30844224, -8581293, 5418197, 9480663, 2231568, -10170080, 33100372, -1306171),
     973            ),
     974            array(
     975                array(15121113, -5201871, -10389905, 15427821, -27509937, -15992507, 21670947, 4486675, -5931810, -14466380),
     976                array(16166486, -9483733, -11104130, 6023908, -31926798, -1364923, 2340060, -16254968, -10735770, -10039824),
     977                array(28042865, -3557089, -12126526, 12259706, -3717498, -6945899, 6766453, -8689599, 18036436, 5803270),
     978            ),
     979        ),
     980        array(
     981            array(
     982                array(-817581, 6763912, 11803561, 1585585, 10958447, -2671165, 23855391, 4598332, -6159431, -14117438),
     983                array(-31031306, -14256194, 17332029, -2383520, 31312682, -5967183, 696309, 50292, -20095739, 11763584),
     984                array(-594563, -2514283, -32234153, 12643980, 12650761, 14811489, 665117, -12613632, -19773211, -10713562),
     985            ),
     986            array(
     987                array(30464590, -11262872, -4127476, -12734478, 19835327, -7105613, -24396175, 2075773, -17020157, 992471),
     988                array(18357185, -6994433, 7766382, 16342475, -29324918, 411174, 14578841, 8080033, -11574335, -10601610),
     989                array(19598397, 10334610, 12555054, 2555664, 18821899, -10339780, 21873263, 16014234, 26224780, 16452269),
     990            ),
     991            array(
     992                array(-30223925, 5145196, 5944548, 16385966, 3976735, 2009897, -11377804, -7618186, -20533829, 3698650),
     993                array(14187449, 3448569, -10636236, -10810935, -22663880, -3433596, 7268410, -10890444, 27394301, 12015369),
     994                array(19695761, 16087646, 28032085, 12999827, 6817792, 11427614, 20244189, -1312777, -13259127, -3402461),
     995            ),
     996            array(
     997                array(30860103, 12735208, -1888245, -4699734, -16974906, 2256940, -8166013, 12298312, -8550524, -10393462),
     998                array(-5719826, -11245325, -1910649, 15569035, 26642876, -7587760, -5789354, -15118654, -4976164, 12651793),
     999                array(-2848395, 9953421, 11531313, -5282879, 26895123, -12697089, -13118820, -16517902, 9768698, -2533218),
     1000            ),
     1001            array(
     1002                array(-24719459, 1894651, -287698, -4704085, 15348719, -8156530, 32767513, 12765450, 4940095, 10678226),
     1003                array(18860224, 15980149, -18987240, -1562570, -26233012, -11071856, -7843882, 13944024, -24372348, 16582019),
     1004                array(-15504260, 4970268, -29893044, 4175593, -20993212, -2199756, -11704054, 15444560, -11003761, 7989037),
     1005            ),
     1006            array(
     1007                array(31490452, 5568061, -2412803, 2182383, -32336847, 4531686, -32078269, 6200206, -19686113, -14800171),
     1008                array(-17308668, -15879940, -31522777, -2831, -32887382, 16375549, 8680158, -16371713, 28550068, -6857132),
     1009                array(-28126887, -5688091, 16837845, -1820458, -6850681, 12700016, -30039981, 4364038, 1155602, 5988841),
     1010            ),
     1011            array(
     1012                array(21890435, -13272907, -12624011, 12154349, -7831873, 15300496, 23148983, -4470481, 24618407, 8283181),
     1013                array(-33136107, -10512751, 9975416, 6841041, -31559793, 16356536, 3070187, -7025928, 1466169, 10740210),
     1014                array(-1509399, -15488185, -13503385, -10655916, 32799044, 909394, -13938903, -5779719, -32164649, -15327040),
     1015            ),
     1016            array(
     1017                array(3960823, -14267803, -28026090, -15918051, -19404858, 13146868, 15567327, 951507, -3260321, -573935),
     1018                array(24740841, 5052253, -30094131, 8961361, 25877428, 6165135, -24368180, 14397372, -7380369, -6144105),
     1019                array(-28888365, 3510803, -28103278, -1158478, -11238128, -10631454, -15441463, -14453128, -1625486, -6494814),
     1020            ),
     1021        ),
     1022        array(
     1023            array(
     1024                array(793299, -9230478, 8836302, -6235707, -27360908, -2369593, 33152843, -4885251, -9906200, -621852),
     1025                array(5666233, 525582, 20782575, -8038419, -24538499, 14657740, 16099374, 1468826, -6171428, -15186581),
     1026                array(-4859255, -3779343, -2917758, -6748019, 7778750, 11688288, -30404353, -9871238, -1558923, -9863646),
     1027            ),
     1028            array(
     1029                array(10896332, -7719704, 824275, 472601, -19460308, 3009587, 25248958, 14783338, -30581476, -15757844),
     1030                array(10566929, 12612572, -31944212, 11118703, -12633376, 12362879, 21752402, 8822496, 24003793, 14264025),
     1031                array(27713862, -7355973, -11008240, 9227530, 27050101, 2504721, 23886875, -13117525, 13958495, -5732453),
     1032            ),
     1033            array(
     1034                array(-23481610, 4867226, -27247128, 3900521, 29838369, -8212291, -31889399, -10041781, 7340521, -15410068),
     1035                array(4646514, -8011124, -22766023, -11532654, 23184553, 8566613, 31366726, -1381061, -15066784, -10375192),
     1036                array(-17270517, 12723032, -16993061, 14878794, 21619651, -6197576, 27584817, 3093888, -8843694, 3849921),
     1037            ),
     1038            array(
     1039                array(-9064912, 2103172, 25561640, -15125738, -5239824, 9582958, 32477045, -9017955, 5002294, -15550259),
     1040                array(-12057553, -11177906, 21115585, -13365155, 8808712, -12030708, 16489530, 13378448, -25845716, 12741426),
     1041                array(-5946367, 10645103, -30911586, 15390284, -3286982, -7118677, 24306472, 15852464, 28834118, -7646072),
     1042            ),
     1043            array(
     1044                array(-17335748, -9107057, -24531279, 9434953, -8472084, -583362, -13090771, 455841, 20461858, 5491305),
     1045                array(13669248, -16095482, -12481974, -10203039, -14569770, -11893198, -24995986, 11293807, -28588204, -9421832),
     1046                array(28497928, 6272777, -33022994, 14470570, 8906179, -1225630, 18504674, -14165166, 29867745, -8795943),
     1047            ),
     1048            array(
     1049                array(-16207023, 13517196, -27799630, -13697798, 24009064, -6373891, -6367600, -13175392, 22853429, -4012011),
     1050                array(24191378, 16712145, -13931797, 15217831, 14542237, 1646131, 18603514, -11037887, 12876623, -2112447),
     1051                array(17902668, 4518229, -411702, -2829247, 26878217, 5258055, -12860753, 608397, 16031844, 3723494),
     1052            ),
     1053            array(
     1054                array(-28632773, 12763728, -20446446, 7577504, 33001348, -13017745, 17558842, -7872890, 23896954, -4314245),
     1055                array(-20005381, -12011952, 31520464, 605201, 2543521, 5991821, -2945064, 7229064, -9919646, -8826859),
     1056                array(28816045, 298879, -28165016, -15920938, 19000928, -1665890, -12680833, -2949325, -18051778, -2082915),
     1057            ),
     1058            array(
     1059                array(16000882, -344896, 3493092, -11447198, -29504595, -13159789, 12577740, 16041268, -19715240, 7847707),
     1060                array(10151868, 10572098, 27312476, 7922682, 14825339, 4723128, -32855931, -6519018, -10020567, 3852848),
     1061                array(-11430470, 15697596, -21121557, -4420647, 5386314, 15063598, 16514493, -15932110, 29330899, -15076224),
     1062            ),
     1063        ),
     1064        array(
     1065            array(
     1066                array(-25499735, -4378794, -15222908, -6901211, 16615731, 2051784, 3303702, 15490, -27548796, 12314391),
     1067                array(15683520, -6003043, 18109120, -9980648, 15337968, -5997823, -16717435, 15921866, 16103996, -3731215),
     1068                array(-23169824, -10781249, 13588192, -1628807, -3798557, -1074929, -19273607, 5402699, -29815713, -9841101),
     1069            ),
     1070            array(
     1071                array(23190676, 2384583, -32714340, 3462154, -29903655, -1529132, -11266856, 8911517, -25205859, 2739713),
     1072                array(21374101, -3554250, -33524649, 9874411, 15377179, 11831242, -33529904, 6134907, 4931255, 11987849),
     1073                array(-7732, -2978858, -16223486, 7277597, 105524, -322051, -31480539, 13861388, -30076310, 10117930),
     1074            ),
     1075            array(
     1076                array(-29501170, -10744872, -26163768, 13051539, -25625564, 5089643, -6325503, 6704079, 12890019, 15728940),
     1077                array(-21972360, -11771379, -951059, -4418840, 14704840, 2695116, 903376, -10428139, 12885167, 8311031),
     1078                array(-17516482, 5352194, 10384213, -13811658, 7506451, 13453191, 26423267, 4384730, 1888765, -5435404),
     1079            ),
     1080            array(
     1081                array(-25817338, -3107312, -13494599, -3182506, 30896459, -13921729, -32251644, -12707869, -19464434, -3340243),
     1082                array(-23607977, -2665774, -526091, 4651136, 5765089, 4618330, 6092245, 14845197, 17151279, -9854116),
     1083                array(-24830458, -12733720, -15165978, 10367250, -29530908, -265356, 22825805, -7087279, -16866484, 16176525),
     1084            ),
     1085            array(
     1086                array(-23583256, 6564961, 20063689, 3798228, -4740178, 7359225, 2006182, -10363426, -28746253, -10197509),
     1087                array(-10626600, -4486402, -13320562, -5125317, 3432136, -6393229, 23632037, -1940610, 32808310, 1099883),
     1088                array(15030977, 5768825, -27451236, -2887299, -6427378, -15361371, -15277896, -6809350, 2051441, -15225865),
     1089            ),
     1090            array(
     1091                array(-3362323, -7239372, 7517890, 9824992, 23555850, 295369, 5148398, -14154188, -22686354, 16633660),
     1092                array(4577086, -16752288, 13249841, -15304328, 19958763, -14537274, 18559670, -10759549, 8402478, -9864273),
     1093                array(-28406330, -1051581, -26790155, -907698, -17212414, -11030789, 9453451, -14980072, 17983010, 9967138),
     1094            ),
     1095            array(
     1096                array(-25762494, 6524722, 26585488, 9969270, 24709298, 1220360, -1677990, 7806337, 17507396, 3651560),
     1097                array(-10420457, -4118111, 14584639, 15971087, -15768321, 8861010, 26556809, -5574557, -18553322, -11357135),
     1098                array(2839101, 14284142, 4029895, 3472686, 14402957, 12689363, -26642121, 8459447, -5605463, -7621941),
     1099            ),
     1100            array(
     1101                array(-4839289, -3535444, 9744961, 2871048, 25113978, 3187018, -25110813, -849066, 17258084, -7977739),
     1102                array(18164541, -10595176, -17154882, -1542417, 19237078, -9745295, 23357533, -15217008, 26908270, 12150756),
     1103                array(-30264870, -7647865, 5112249, -7036672, -1499807, -6974257, 43168, -5537701, -32302074, 16215819),
     1104            ),
     1105        ),
     1106        array(
     1107            array(
     1108                array(-6898905, 9824394, -12304779, -4401089, -31397141, -6276835, 32574489, 12532905, -7503072, -8675347),
     1109                array(-27343522, -16515468, -27151524, -10722951, 946346, 16291093, 254968, 7168080, 21676107, -1943028),
     1110                array(21260961, -8424752, -16831886, -11920822, -23677961, 3968121, -3651949, -6215466, -3556191, -7913075),
     1111            ),
     1112            array(
     1113                array(16544754, 13250366, -16804428, 15546242, -4583003, 12757258, -2462308, -8680336, -18907032, -9662799),
     1114                array(-2415239, -15577728, 18312303, 4964443, -15272530, -12653564, 26820651, 16690659, 25459437, -4564609),
     1115                array(-25144690, 11425020, 28423002, -11020557, -6144921, -15826224, 9142795, -2391602, -6432418, -1644817),
     1116            ),
     1117            array(
     1118                array(-23104652, 6253476, 16964147, -3768872, -25113972, -12296437, -27457225, -16344658, 6335692, 7249989),
     1119                array(-30333227, 13979675, 7503222, -12368314, -11956721, -4621693, -30272269, 2682242, 25993170, -12478523),
     1120                array(4364628, 5930691, 32304656, -10044554, -8054781, 15091131, 22857016, -10598955, 31820368, 15075278),
     1121            ),
     1122            array(
     1123                array(31879134, -8918693, 17258761, 90626, -8041836, -4917709, 24162788, -9650886, -17970238, 12833045),
     1124                array(19073683, 14851414, -24403169, -11860168, 7625278, 11091125, -19619190, 2074449, -9413939, 14905377),
     1125                array(24483667, -11935567, -2518866, -11547418, -1553130, 15355506, -25282080, 9253129, 27628530, -7555480),
     1126            ),
     1127            array(
     1128                array(17597607, 8340603, 19355617, 552187, 26198470, -3176583, 4593324, -9157582, -14110875, 15297016),
     1129                array(510886, 14337390, -31785257, 16638632, 6328095, 2713355, -20217417, -11864220, 8683221, 2921426),
     1130                array(18606791, 11874196, 27155355, -5281482, -24031742, 6265446, -25178240, -1278924, 4674690, 13890525),
     1131            ),
     1132            array(
     1133                array(13609624, 13069022, -27372361, -13055908, 24360586, 9592974, 14977157, 9835105, 4389687, 288396),
     1134                array(9922506, -519394, 13613107, 5883594, -18758345, -434263, -12304062, 8317628, 23388070, 16052080),
     1135                array(12720016, 11937594, -31970060, -5028689, 26900120, 8561328, -20155687, -11632979, -14754271, -10812892),
     1136            ),
     1137            array(
     1138                array(15961858, 14150409, 26716931, -665832, -22794328, 13603569, 11829573, 7467844, -28822128, 929275),
     1139                array(11038231, -11582396, -27310482, -7316562, -10498527, -16307831, -23479533, -9371869, -21393143, 2465074),
     1140                array(20017163, -4323226, 27915242, 1529148, 12396362, 15675764, 13817261, -9658066, 2463391, -4622140),
     1141            ),
     1142            array(
     1143                array(-16358878, -12663911, -12065183, 4996454, -1256422, 1073572, 9583558, 12851107, 4003896, 12673717),
     1144                array(-1731589, -15155870, -3262930, 16143082, 19294135, 13385325, 14741514, -9103726, 7903886, 2348101),
     1145                array(24536016, -16515207, 12715592, -3862155, 1511293, 10047386, -3842346, -7129159, -28377538, 10048127),
     1146            ),
     1147        ),
     1148        array(
     1149            array(
     1150                array(-12622226, -6204820, 30718825, 2591312, -10617028, 12192840, 18873298, -7297090, -32297756, 15221632),
     1151                array(-26478122, -11103864, 11546244, -1852483, 9180880, 7656409, -21343950, 2095755, 29769758, 6593415),
     1152                array(-31994208, -2907461, 4176912, 3264766, 12538965, -868111, 26312345, -6118678, 30958054, 8292160),
     1153            ),
     1154            array(
     1155                array(31429822, -13959116, 29173532, 15632448, 12174511, -2760094, 32808831, 3977186, 26143136, -3148876),
     1156                array(22648901, 1402143, -22799984, 13746059, 7936347, 365344, -8668633, -1674433, -3758243, -2304625),
     1157                array(-15491917, 8012313, -2514730, -12702462, -23965846, -10254029, -1612713, -1535569, -16664475, 8194478),
     1158            ),
     1159            array(
     1160                array(27338066, -7507420, -7414224, 10140405, -19026427, -6589889, 27277191, 8855376, 28572286, 3005164),
     1161                array(26287124, 4821776, 25476601, -4145903, -3764513, -15788984, -18008582, 1182479, -26094821, -13079595),
     1162                array(-7171154, 3178080, 23970071, 6201893, -17195577, -4489192, -21876275, -13982627, 32208683, -1198248),
     1163            ),
     1164            array(
     1165                array(-16657702, 2817643, -10286362, 14811298, 6024667, 13349505, -27315504, -10497842, -27672585, -11539858),
     1166                array(15941029, -9405932, -21367050, 8062055, 31876073, -238629, -15278393, -1444429, 15397331, -4130193),
     1167                array(8934485, -13485467, -23286397, -13423241, -32446090, 14047986, 31170398, -1441021, -27505566, 15087184),
     1168            ),
     1169            array(
     1170                array(-18357243, -2156491, 24524913, -16677868, 15520427, -6360776, -15502406, 11461896, 16788528, -5868942),
     1171                array(-1947386, 16013773, 21750665, 3714552, -17401782, -16055433, -3770287, -10323320, 31322514, -11615635),
     1172                array(21426655, -5650218, -13648287, -5347537, -28812189, -4920970, -18275391, -14621414, 13040862, -12112948),
     1173            ),
     1174            array(
     1175                array(11293895, 12478086, -27136401, 15083750, -29307421, 14748872, 14555558, -13417103, 1613711, 4896935),
     1176                array(-25894883, 15323294, -8489791, -8057900, 25967126, -13425460, 2825960, -4897045, -23971776, -11267415),
     1177                array(-15924766, -5229880, -17443532, 6410664, 3622847, 10243618, 20615400, 12405433, -23753030, -8436416),
     1178            ),
     1179            array(
     1180                array(-7091295, 12556208, -20191352, 9025187, -17072479, 4333801, 4378436, 2432030, 23097949, -566018),
     1181                array(4565804, -16025654, 20084412, -7842817, 1724999, 189254, 24767264, 10103221, -18512313, 2424778),
     1182                array(366633, -11976806, 8173090, -6890119, 30788634, 5745705, -7168678, 1344109, -3642553, 12412659),
     1183            ),
     1184            array(
     1185                array(-24001791, 7690286, 14929416, -168257, -32210835, -13412986, 24162697, -15326504, -3141501, 11179385),
     1186                array(18289522, -14724954, 8056945, 16430056, -21729724, 7842514, -6001441, -1486897, -18684645, -11443503),
     1187                array(476239, 6601091, -6152790, -9723375, 17503545, -4863900, 27672959, 13403813, 11052904, 5219329),
     1188            ),
     1189        ),
     1190        array(
     1191            array(
     1192                array(20678546, -8375738, -32671898, 8849123, -5009758, 14574752, 31186971, -3973730, 9014762, -8579056),
     1193                array(-13644050, -10350239, -15962508, 5075808, -1514661, -11534600, -33102500, 9160280, 8473550, -3256838),
     1194                array(24900749, 14435722, 17209120, -15292541, -22592275, 9878983, -7689309, -16335821, -24568481, 11788948),
     1195            ),
     1196            array(
     1197                array(-3118155, -11395194, -13802089, 14797441, 9652448, -6845904, -20037437, 10410733, -24568470, -1458691),
     1198                array(-15659161, 16736706, -22467150, 10215878, -9097177, 7563911, 11871841, -12505194, -18513325, 8464118),
     1199                array(-23400612, 8348507, -14585951, -861714, -3950205, -6373419, 14325289, 8628612, 33313881, -8370517),
     1200            ),
     1201            array(
     1202                array(-20186973, -4967935, 22367356, 5271547, -1097117, -4788838, -24805667, -10236854, -8940735, -5818269),
     1203                array(-6948785, -1795212, -32625683, -16021179, 32635414, -7374245, 15989197, -12838188, 28358192, -4253904),
     1204                array(-23561781, -2799059, -32351682, -1661963, -9147719, 10429267, -16637684, 4072016, -5351664, 5596589),
     1205            ),
     1206            array(
     1207                array(-28236598, -3390048, 12312896, 6213178, 3117142, 16078565, 29266239, 2557221, 1768301, 15373193),
     1208                array(-7243358, -3246960, -4593467, -7553353, -127927, -912245, -1090902, -4504991, -24660491, 3442910),
     1209                array(-30210571, 5124043, 14181784, 8197961, 18964734, -11939093, 22597931, 7176455, -18585478, 13365930),
     1210            ),
     1211            array(
     1212                array(-7877390, -1499958, 8324673, 4690079, 6261860, 890446, 24538107, -8570186, -9689599, -3031667),
     1213                array(25008904, -10771599, -4305031, -9638010, 16265036, 15721635, 683793, -11823784, 15723479, -15163481),
     1214                array(-9660625, 12374379, -27006999, -7026148, -7724114, -12314514, 11879682, 5400171, 519526, -1235876),
     1215            ),
     1216            array(
     1217                array(22258397, -16332233, -7869817, 14613016, -22520255, -2950923, -20353881, 7315967, 16648397, 7605640),
     1218                array(-8081308, -8464597, -8223311, 9719710, 19259459, -15348212, 23994942, -5281555, -9468848, 4763278),
     1219                array(-21699244, 9220969, -15730624, 1084137, -25476107, -2852390, 31088447, -7764523, -11356529, 728112),
     1220            ),
     1221            array(
     1222                array(26047220, -11751471, -6900323, -16521798, 24092068, 9158119, -4273545, -12555558, -29365436, -5498272),
     1223                array(17510331, -322857, 5854289, 8403524, 17133918, -3112612, -28111007, 12327945, 10750447, 10014012),
     1224                array(-10312768, 3936952, 9156313, -8897683, 16498692, -994647, -27481051, -666732, 3424691, 7540221),
     1225            ),
     1226            array(
     1227                array(30322361, -6964110, 11361005, -4143317, 7433304, 4989748, -7071422, -16317219, -9244265, 15258046),
     1228                array(13054562, -2779497, 19155474, 469045, -12482797, 4566042, 5631406, 2711395, 1062915, -5136345),
     1229                array(-19240248, -11254599, -29509029, -7499965, -5835763, 13005411, -6066489, 12194497, 32960380, 1459310),
     1230            ),
     1231        ),
     1232        array(
     1233            array(
     1234                array(19852034, 7027924, 23669353, 10020366, 8586503, -6657907, 394197, -6101885, 18638003, -11174937),
     1235                array(31395534, 15098109, 26581030, 8030562, -16527914, -5007134, 9012486, -7584354, -6643087, -5442636),
     1236                array(-9192165, -2347377, -1997099, 4529534, 25766844, 607986, -13222, 9677543, -32294889, -6456008),
     1237            ),
     1238            array(
     1239                array(-2444496, -149937, 29348902, 8186665, 1873760, 12489863, -30934579, -7839692, -7852844, -8138429),
     1240                array(-15236356, -15433509, 7766470, 746860, 26346930, -10221762, -27333451, 10754588, -9431476, 5203576),
     1241                array(31834314, 14135496, -770007, 5159118, 20917671, -16768096, -7467973, -7337524, 31809243, 7347066),
     1242            ),
     1243            array(
     1244                array(-9606723, -11874240, 20414459, 13033986, 13716524, -11691881, 19797970, -12211255, 15192876, -2087490),
     1245                array(-12663563, -2181719, 1168162, -3804809, 26747877, -14138091, 10609330, 12694420, 33473243, -13382104),
     1246                array(33184999, 11180355, 15832085, -11385430, -1633671, 225884, 15089336, -11023903, -6135662, 14480053),
     1247            ),
     1248            array(
     1249                array(31308717, -5619998, 31030840, -1897099, 15674547, -6582883, 5496208, 13685227, 27595050, 8737275),
     1250                array(-20318852, -15150239, 10933843, -16178022, 8335352, -7546022, -31008351, -12610604, 26498114, 66511),
     1251                array(22644454, -8761729, -16671776, 4884562, -3105614, -13559366, 30540766, -4286747, -13327787, -7515095),
     1252            ),
     1253            array(
     1254                array(-28017847, 9834845, 18617207, -2681312, -3401956, -13307506, 8205540, 13585437, -17127465, 15115439),
     1255                array(23711543, -672915, 31206561, -8362711, 6164647, -9709987, -33535882, -1426096, 8236921, 16492939),
     1256                array(-23910559, -13515526, -26299483, -4503841, 25005590, -7687270, 19574902, 10071562, 6708380, -6222424),
     1257            ),
     1258            array(
     1259                array(2101391, -4930054, 19702731, 2367575, -15427167, 1047675, 5301017, 9328700, 29955601, -11678310),
     1260                array(3096359, 9271816, -21620864, -15521844, -14847996, -7592937, -25892142, -12635595, -9917575, 6216608),
     1261                array(-32615849, 338663, -25195611, 2510422, -29213566, -13820213, 24822830, -6146567, -26767480, 7525079),
     1262            ),
     1263            array(
     1264                array(-23066649, -13985623, 16133487, -7896178, -3389565, 778788, -910336, -2782495, -19386633, 11994101),
     1265                array(21691500, -13624626, -641331, -14367021, 3285881, -3483596, -25064666, 9718258, -7477437, 13381418),
     1266                array(18445390, -4202236, 14979846, 11622458, -1727110, -3582980, 23111648, -6375247, 28535282, 15779576),
     1267            ),
     1268            array(
     1269                array(30098053, 3089662, -9234387, 16662135, -21306940, 11308411, -14068454, 12021730, 9955285, -16303356),
     1270                array(9734894, -14576830, -7473633, -9138735, 2060392, 11313496, -18426029, 9924399, 20194861, 13380996),
     1271                array(-26378102, -7965207, -22167821, 15789297, -18055342, -6168792, -1984914, 15707771, 26342023, 10146099),
     1272            ),
     1273        ),
     1274        array(
     1275            array(
     1276                array(-26016874, -219943, 21339191, -41388, 19745256, -2878700, -29637280, 2227040, 21612326, -545728),
     1277                array(-13077387, 1184228, 23562814, -5970442, -20351244, -6348714, 25764461, 12243797, -20856566, 11649658),
     1278                array(-10031494, 11262626, 27384172, 2271902, 26947504, -15997771, 39944, 6114064, 33514190, 2333242),
     1279            ),
     1280            array(
     1281                array(-21433588, -12421821, 8119782, 7219913, -21830522, -9016134, -6679750, -12670638, 24350578, -13450001),
     1282                array(-4116307, -11271533, -23886186, 4843615, -30088339, 690623, -31536088, -10406836, 8317860, 12352766),
     1283                array(18200138, -14475911, -33087759, -2696619, -23702521, -9102511, -23552096, -2287550, 20712163, 6719373),
     1284            ),
     1285            array(
     1286                array(26656208, 6075253, -7858556, 1886072, -28344043, 4262326, 11117530, -3763210, 26224235, -3297458),
     1287                array(-17168938, -14854097, -3395676, -16369877, -19954045, 14050420, 21728352, 9493610, 18620611, -16428628),
     1288                array(-13323321, 13325349, 11432106, 5964811, 18609221, 6062965, -5269471, -9725556, -30701573, -16479657),
     1289            ),
     1290            array(
     1291                array(-23860538, -11233159, 26961357, 1640861, -32413112, -16737940, 12248509, -5240639, 13735342, 1934062),
     1292                array(25089769, 6742589, 17081145, -13406266, 21909293, -16067981, -15136294, -3765346, -21277997, 5473616),
     1293                array(31883677, -7961101, 1083432, -11572403, 22828471, 13290673, -7125085, 12469656, 29111212, -5451014),
     1294            ),
     1295            array(
     1296                array(24244947, -15050407, -26262976, 2791540, -14997599, 16666678, 24367466, 6388839, -10295587, 452383),
     1297                array(-25640782, -3417841, 5217916, 16224624, 19987036, -4082269, -24236251, -5915248, 15766062, 8407814),
     1298                array(-20406999, 13990231, 15495425, 16395525, 5377168, 15166495, -8917023, -4388953, -8067909, 2276718),
     1299            ),
     1300            array(
     1301                array(30157918, 12924066, -17712050, 9245753, 19895028, 3368142, -23827587, 5096219, 22740376, -7303417),
     1302                array(2041139, -14256350, 7783687, 13876377, -25946985, -13352459, 24051124, 13742383, -15637599, 13295222),
     1303                array(33338237, -8505733, 12532113, 7977527, 9106186, -1715251, -17720195, -4612972, -4451357, -14669444),
     1304            ),
     1305            array(
     1306                array(-20045281, 5454097, -14346548, 6447146, 28862071, 1883651, -2469266, -4141880, 7770569, 9620597),
     1307                array(23208068, 7979712, 33071466, 8149229, 1758231, -10834995, 30945528, -1694323, -33502340, -14767970),
     1308                array(1439958, -16270480, -1079989, -793782, 4625402, 10647766, -5043801, 1220118, 30494170, -11440799),
     1309            ),
     1310            array(
     1311                array(-5037580, -13028295, -2970559, -3061767, 15640974, -6701666, -26739026, 926050, -1684339, -13333647),
     1312                array(13908495, -3549272, 30919928, -6273825, -21521863, 7989039, 9021034, 9078865, 3353509, 4033511),
     1313                array(-29663431, -15113610, 32259991, -344482, 24295849, -12912123, 23161163, 8839127, 27485041, 7356032),
     1314            ),
     1315        ),
     1316        array(
     1317            array(
     1318                array(9661027, 705443, 11980065, -5370154, -1628543, 14661173, -6346142, 2625015, 28431036, -16771834),
     1319                array(-23839233, -8311415, -25945511, 7480958, -17681669, -8354183, -22545972, 14150565, 15970762, 4099461),
     1320                array(29262576, 16756590, 26350592, -8793563, 8529671, -11208050, 13617293, -9937143, 11465739, 8317062),
     1321            ),
     1322            array(
     1323                array(-25493081, -6962928, 32500200, -9419051, -23038724, -2302222, 14898637, 3848455, 20969334, -5157516),
     1324                array(-20384450, -14347713, -18336405, 13884722, -33039454, 2842114, -21610826, -3649888, 11177095, 14989547),
     1325                array(-24496721, -11716016, 16959896, 2278463, 12066309, 10137771, 13515641, 2581286, -28487508, 9930240),
     1326            ),
     1327            array(
     1328                array(-17751622, -2097826, 16544300, -13009300, -15914807, -14949081, 18345767, -13403753, 16291481, -5314038),
     1329                array(-33229194, 2553288, 32678213, 9875984, 8534129, 6889387, -9676774, 6957617, 4368891, 9788741),
     1330                array(16660756, 7281060, -10830758, 12911820, 20108584, -8101676, -21722536, -8613148, 16250552, -11111103),
     1331            ),
     1332            array(
     1333                array(-19765507, 2390526, -16551031, 14161980, 1905286, 6414907, 4689584, 10604807, -30190403, 4782747),
     1334                array(-1354539, 14736941, -7367442, -13292886, 7710542, -14155590, -9981571, 4383045, 22546403, 437323),
     1335                array(31665577, -12180464, -16186830, 1491339, -18368625, 3294682, 27343084, 2786261, -30633590, -14097016),
     1336            ),
     1337            array(
     1338                array(-14467279, -683715, -33374107, 7448552, 19294360, 14334329, -19690631, 2355319, -19284671, -6114373),
     1339                array(15121312, -15796162, 6377020, -6031361, -10798111, -12957845, 18952177, 15496498, -29380133, 11754228),
     1340                array(-2637277, -13483075, 8488727, -14303896, 12728761, -1622493, 7141596, 11724556, 22761615, -10134141),
     1341            ),
     1342            array(
     1343                array(16918416, 11729663, -18083579, 3022987, -31015732, -13339659, -28741185, -12227393, 32851222, 11717399),
     1344                array(11166634, 7338049, -6722523, 4531520, -29468672, -7302055, 31474879, 3483633, -1193175, -4030831),
     1345                array(-185635, 9921305, 31456609, -13536438, -12013818, 13348923, 33142652, 6546660, -19985279, -3948376),
     1346            ),
     1347            array(
     1348                array(-32460596, 11266712, -11197107, -7899103, 31703694, 3855903, -8537131, -12833048, -30772034, -15486313),
     1349                array(-18006477, 12709068, 3991746, -6479188, -21491523, -10550425, -31135347, -16049879, 10928917, 3011958),
     1350                array(-6957757, -15594337, 31696059, 334240, 29576716, 14796075, -30831056, -12805180, 18008031, 10258577),
     1351            ),
     1352            array(
     1353                array(-22448644, 15655569, 7018479, -4410003, -30314266, -1201591, -1853465, 1367120, 25127874, 6671743),
     1354                array(29701166, -14373934, -10878120, 9279288, -17568, 13127210, 21382910, 11042292, 25838796, 4642684),
     1355                array(-20430234, 14955537, -24126347, 8124619, -5369288, -5990470, 30468147, -13900640, 18423289, 4177476),
     1356            ),
     1357        )
     1358    );
     1359
     1360    /**
     1361     * See: libsodium's crypto_core/curve25519/ref10/base2.h
     1362     *
     1363     * @var array basically int[8][3]
     1364     */
     1365    protected static $base2 = array(
     1366        array(
     1367            array(25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626, -11754271, -6079156, 2047605),
     1368            array(-12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692, 5043384, 19500929, -15469378),
     1369            array(-8738181, 4489570, 9688441, -14785194, 10184609, -12363380, 29287919, 11864899, -24514362, -4438546),
     1370        ),
     1371        array(
     1372            array(15636291, -9688557, 24204773, -7912398, 616977, -16685262, 27787600, -14772189, 28944400, -1550024),
     1373            array(16568933, 4717097, -11556148, -1102322, 15682896, -11807043, 16354577, -11775962, 7689662, 11199574),
     1374            array(30464156, -5976125, -11779434, -15670865, 23220365, 15915852, 7512774, 10017326, -17749093, -9920357),
     1375        ),
     1376        array(
     1377            array(10861363, 11473154, 27284546, 1981175, -30064349, 12577861, 32867885, 14515107, -15438304, 10819380),
     1378            array(4708026, 6336745, 20377586, 9066809, -11272109, 6594696, -25653668, 12483688, -12668491, 5581306),
     1379            array(19563160, 16186464, -29386857, 4097519, 10237984, -4348115, 28542350, 13850243, -23678021, -15815942),
     1380        ),
     1381        array(
     1382            array(5153746, 9909285, 1723747, -2777874, 30523605, 5516873, 19480852, 5230134, -23952439, -15175766),
     1383            array(-30269007, -3463509, 7665486, 10083793, 28475525, 1649722, 20654025, 16520125, 30598449, 7715701),
     1384            array(28881845, 14381568, 9657904, 3680757, -20181635, 7843316, -31400660, 1370708, 29794553, -1409300),
     1385        ),
     1386        array(
     1387            array(-22518993, -6692182, 14201702, -8745502, -23510406, 8844726, 18474211, -1361450, -13062696, 13821877),
     1388            array(-6455177, -7839871, 3374702, -4740862, -27098617, -10571707, 31655028, -7212327, 18853322, -14220951),
     1389            array(4566830, -12963868, -28974889, -12240689, -7602672, -2830569, -8514358, -10431137, 2207753, -3209784),
     1390        ),
     1391        array(
     1392            array(-25154831, -4185821, 29681144, 7868801, -6854661, -9423865, -12437364, -663000, -31111463, -16132436),
     1393            array(25576264, -2703214, 7349804, -11814844, 16472782, 9300885, 3844789, 15725684, 171356, 6466918),
     1394            array(23103977, 13316479, 9739013, -16149481, 817875, -15038942, 8965339, -14088058, -30714912, 16193877),
     1395        ),
     1396        array(
     1397            array(-33521811, 3180713, -2394130, 14003687, -16903474, -16270840, 17238398, 4729455, -18074513, 9256800),
     1398            array(-25182317, -4174131, 32336398, 5036987, -21236817, 11360617, 22616405, 9761698, -19827198, 630305),
     1399            array(-13720693, 2639453, -24237460, -7406481, 9494427, -5774029, -6554551, -15960994, -2449256, -14291300),
     1400        ),
     1401        array(
     1402            array(-3151181, -5046075, 9282714, 6866145, -31907062, -863023, -18940575, 15033784, 25105118, -7894876),
     1403            array(-24326370, 15950226, -31801215, -14592823, -11662737, -5090925, 1573892, -2625887, 2198790, -15804619),
     1404            array(-3099351, 10324967, -2241613, 7453183, -5446979, -2735503, -13812022, -16236442, -32461234, -12290683),
     1405        )
     1406    );
     1407
     1408    /**
     1409     * 37095705934669439343138083508754565189542113879843219016388785533085940283555
     1410     *
     1411     * @var int[]
     1412     */
     1413    protected static $d = array(
     1414        -10913610,
     1415        13857413,
     1416        -15372611,
     1417        6949391,
     1418        114729,
     1419        -8787816,
     1420        -6275908,
     1421        -3247719,
     1422        -18696448,
     1423        -12055116
     1424    );
     1425
     1426    /**
     1427     * 2 * d = 16295367250680780974490674513165176452449235426866156013048779062215315747161
     1428     *
     1429     * @var int[]
     1430     */
     1431    protected static $d2 = array(
     1432        -21827239,
     1433        -5839606,
     1434        -30745221,
     1435        13898782,
     1436        229458,
     1437        15978800,
     1438        -12551817,
     1439        -6495438,
     1440        29715968,
     1441        9444199
     1442    );
     1443
     1444    /**
     1445     * sqrt(-1)
     1446     *
     1447     * @var int[]
     1448     */
     1449    protected static $sqrtm1 = array(
     1450        -32595792,
     1451        -7943725,
     1452        9377950,
     1453        3500415,
     1454        12389472,
     1455        -272473,
     1456        -25146209,
     1457        -2005654,
     1458        326686,
     1459        11406482
     1460    );
     1461}
     1462 No newline at end of file
  • wp-includes/sodium_compat/src/Core/Curve25519.php

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
     1<?php
     2
     3/**
     4 * Class ParagonIE_Sodium_Core_Curve25519
     5 *
     6 * Implements Curve25519 core functions
     7 *
     8 * Based on the ref10 curve25519 code provided by libsodium
     9 *
     10 * @ref https://github.com/jedisct1/libsodium/blob/master/src/libsodium/crypto_core/curve25519/ref10/curve25519_ref10.c
     11 */
     12abstract class ParagonIE_Sodium_Core_Curve25519 extends ParagonIE_Sodium_Core_Curve25519_H
     13{
     14    /**
     15     * Get a field element of size 10 with a value of 0
     16     *
     17     * @return ParagonIE_Sodium_Core_Curve25519_Fe
     18     */
     19    public static function fe_0()
     20    {
     21        return ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(array(
     22            0,
     23            0,
     24            0,
     25            0,
     26            0,
     27            0,
     28            0,
     29            0,
     30            0,
     31            0
     32        ));
     33    }
     34
     35    /**
     36     * Get a field element of size 10 with a value of 1
     37     *
     38     * @return ParagonIE_Sodium_Core_Curve25519_Fe
     39     */
     40    public static function fe_1()
     41    {
     42        return ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(array(
     43            1,
     44            0,
     45            0,
     46            0,
     47            0,
     48            0,
     49            0,
     50            0,
     51            0,
     52            0
     53        ));
     54    }
     55
     56    /**
     57     * Add two field elements.
     58     *
     59     * @param ParagonIE_Sodium_Core_Curve25519_Fe $f
     60     * @param ParagonIE_Sodium_Core_Curve25519_Fe $g
     61     * @return ParagonIE_Sodium_Core_Curve25519_Fe
     62     */
     63    public static function fe_add(
     64        ParagonIE_Sodium_Core_Curve25519_Fe $f,
     65        ParagonIE_Sodium_Core_Curve25519_Fe $g
     66    ) {
     67        $arr = array();
     68        for ($i = 0; $i < 10; ++$i) {
     69            $arr[$i] = (int) ($f[$i] + $g[$i]);
     70        }
     71        return ParagonIE_Sodium_Core_Curve25519_Fe::fromArray($arr);
     72    }
     73
     74    /**
     75     * Constant-time conditional move.
     76     *
     77     * @param ParagonIE_Sodium_Core_Curve25519_Fe $f
     78     * @param ParagonIE_Sodium_Core_Curve25519_Fe $g
     79     * @param int $b
     80     * @return ParagonIE_Sodium_Core_Curve25519_Fe
     81     */
     82    public static function fe_cmov(
     83        ParagonIE_Sodium_Core_Curve25519_Fe $f,
     84        ParagonIE_Sodium_Core_Curve25519_Fe $g,
     85        $b = 0
     86    ) {
     87        $h = array();
     88        $b *= -1;
     89        for ($i = 0; $i < 10; ++$i) {
     90            $x = (($f[$i] ^ $g[$i]) & $b);
     91            $h[$i] = $f[$i] ^ $x;
     92        }
     93        return ParagonIE_Sodium_Core_Curve25519_Fe::fromArray($h);
     94    }
     95
     96    /**
     97     * Create a copy of a field element.
     98     *
     99     * @param ParagonIE_Sodium_Core_Curve25519_Fe $f
     100     * @return ParagonIE_Sodium_Core_Curve25519_Fe
     101     */
     102    public static function fe_copy(ParagonIE_Sodium_Core_Curve25519_Fe $f)
     103    {
     104        $h = clone $f;
     105        return $h;
     106    }
     107
     108    /**
     109     * Give: 32-byte string.
     110     * Receive: A field element object to use for internal calculations.
     111     *
     112     * @param string $s
     113     * @return ParagonIE_Sodium_Core_Curve25519_Fe
     114     * @throws RangeException
     115     */
     116    public static function fe_frombytes($s)
     117    {
     118        if (self::strlen($s) !== 32) {
     119            throw new RangeException('Expected a 32-byte string.');
     120        }
     121        $h0 = self::load_4($s);
     122        $h1 = self::load_3(self::substr($s, 4, 3)) << 6;
     123        $h2 = self::load_3(self::substr($s, 7, 3)) << 5;
     124        $h3 = self::load_3(self::substr($s, 10, 3)) << 3;
     125        $h4 = self::load_3(self::substr($s, 13, 3)) << 2;
     126        $h5 = self::load_4(self::substr($s, 16, 4));
     127        $h6 = self::load_3(self::substr($s, 20, 3)) << 7;
     128        $h7 = self::load_3(self::substr($s, 23, 3)) << 5;
     129        $h8 = self::load_3(self::substr($s, 26, 3)) << 4;
     130        $h9 = (self::load_3(self::substr($s, 29, 3)) & 8388607) << 2;
     131
     132        $carry9 = ($h9 + (1 << 24)) >> 25;
     133        $h0 += $carry9 * 19;
     134        $h9 -= $carry9 * (1 << 25);
     135        $carry1 = ($h1 + (1 << 24)) >> 25;
     136        $h2 += $carry1;
     137        $h1 -= $carry1 * (1 << 25);
     138        $carry3 = ($h3 + (1 << 24)) >> 25;
     139        $h4 += $carry3;
     140        $h3 -= $carry3 * (1 << 25);
     141        $carry5 = ($h5 + (1 << 24)) >> 25;
     142        $h6 += $carry5;
     143        $h5 -= $carry5 * (1 << 25);
     144        $carry7 = ($h7 + (1 << 24)) >> 25;
     145        $h8 += $carry7;
     146        $h7 -= $carry7 * (1 << 25);
     147
     148        $carry0 = ($h0 + (1 << 25)) >> 26;
     149        $h1 += $carry0;
     150        $h0 -= $carry0 * (1 << 26);
     151        $carry2 = ($h2 + (1 << 25)) >> 26;
     152        $h3 += $carry2;
     153        $h2 -= $carry2 * (1 << 26);
     154        $carry4 = ($h4 + (1 << 25)) >> 26;
     155        $h5 += $carry4;
     156        $h4 -= $carry4 * (1 << 26);
     157        $carry6 = ($h6 + (1 << 25)) >> 26;
     158        $h7 += $carry6;
     159        $h6 -= $carry6 * (1 << 26);
     160        $carry8 = ($h8 + (1 << 25)) >> 26;
     161        $h9 += $carry8;
     162        $h8 -= $carry8 * (1 << 26);
     163
     164        return ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
     165            array(
     166                (int) $h0,
     167                (int) $h1,
     168                (int) $h2,
     169                (int) $h3,
     170                (int) $h4,
     171                (int) $h5,
     172                (int) $h6,
     173                (int) $h7,
     174                (int) $h8,
     175                (int) $h9
     176            )
     177        );
     178    }
     179
     180    /**
     181     * Convert a field element to a byte string.
     182     *
     183     * @param ParagonIE_Sodium_Core_Curve25519_Fe $h
     184     * @return string
     185     */
     186    public static function fe_tobytes(ParagonIE_Sodium_Core_Curve25519_Fe $h)
     187    {
     188        $h[0] = (int) $h[0];
     189        $h[1] = (int) $h[1];
     190        $h[2] = (int) $h[2];
     191        $h[3] = (int) $h[3];
     192        $h[4] = (int) $h[4];
     193        $h[5] = (int) $h[5];
     194        $h[6] = (int) $h[6];
     195        $h[7] = (int) $h[7];
     196        $h[8] = (int) $h[8];
     197        $h[9] = (int) $h[9];
     198
     199        $q = (19 * $h[9] + (1 << 24)) >> 25;
     200        $q = ($h[0] + $q) >> 26;
     201        $q = ($h[1] + $q) >> 25;
     202        $q = ($h[2] + $q) >> 26;
     203        $q = ($h[3] + $q) >> 25;
     204        $q = ($h[4] + $q) >> 26;
     205        $q = ($h[5] + $q) >> 25;
     206        $q = ($h[6] + $q) >> 26;
     207        $q = ($h[7] + $q) >> 25;
     208        $q = ($h[8] + $q) >> 26;
     209        $q = ($h[9] + $q) >> 25;
     210
     211        $h[0] += 19 * $q;
     212
     213        $carry0 = $h[0] >> 26;
     214        $h[1] += $carry0;
     215        $h[0] -= $carry0 * (1 << 26);
     216        $carry1 = $h[1] >> 25;
     217        $h[2] += $carry1;
     218        $h[1] -= $carry1 * (1 << 25);
     219        $carry2 = $h[2] >> 26;
     220        $h[3] += $carry2;
     221        $h[2] -= $carry2 * (1 << 26);
     222        $carry3 = $h[3] >> 25;
     223        $h[4] += $carry3;
     224        $h[3] -= $carry3 * (1 << 25);
     225        $carry4 = $h[4] >> 26;
     226        $h[5] += $carry4;
     227        $h[4] -= $carry4 * (1 << 26);
     228        $carry5 = $h[5] >> 25;
     229        $h[6] += $carry5;
     230        $h[5] -= $carry5 * (1 << 25);
     231        $carry6 = $h[6] >> 26;
     232        $h[7] += $carry6;
     233        $h[6] -= $carry6 * (1 << 26);
     234        $carry7 = $h[7] >> 25;
     235        $h[8] += $carry7;
     236        $h[7] -= $carry7 * (1 << 25);
     237        $carry8 = $h[8] >> 26;
     238        $h[9] += $carry8;
     239        $h[8] -= $carry8 * (1 << 26);
     240        $carry9 = $h[9] >> 25;
     241        $h[9] -= $carry9 * (1 << 25);
     242
     243        $s = array();
     244        $s[0] = ($h[0] >> 0) & 0xff;
     245        $s[1] = ($h[0] >> 8) & 0xff;
     246        $s[2] = ($h[0] >> 16) & 0xff;
     247        $s[3] = (($h[0] >> 24) | ($h[1] << 2)) & 0xff;
     248        $s[4] = ($h[1] >> 6) & 0xff;
     249        $s[5] = ($h[1] >> 14) & 0xff;
     250        $s[6] = (($h[1] >> 22) | ($h[2] << 3)) & 0xff;
     251        $s[7] = ($h[2] >> 5) & 0xff;
     252        $s[8] = ($h[2] >> 13) & 0xff;
     253        $s[9] = (($h[2] >> 21) | ($h[3] << 5)) & 0xff;
     254        $s[10] = ($h[3] >> 3) & 0xff;
     255        $s[11] = ($h[3] >> 11) & 0xff;
     256        $s[12] = (($h[3] >> 19) | ($h[4] << 6)) & 0xff;
     257        $s[13] = ($h[4] >> 2) & 0xff;
     258        $s[14] = ($h[4] >> 10) & 0xff;
     259        $s[15] = ($h[4] >> 18) & 0xff;
     260        $s[16] = ($h[5] >> 0) & 0xff;
     261        $s[17] = ($h[5] >> 8) & 0xff;
     262        $s[18] = ($h[5] >> 16) & 0xff;
     263        $s[19] = (($h[5] >> 24) | ($h[6] << 1)) & 0xff;
     264        $s[20] = ($h[6] >> 7) & 0xff;
     265        $s[21] = ($h[6] >> 15) & 0xff;
     266        $s[22] = (($h[6] >> 23) | ($h[7] << 3)) & 0xff;
     267        $s[23] = ($h[7] >> 5) & 0xff;
     268        $s[24] = ($h[7] >> 13) & 0xff;
     269        $s[25] = (($h[7] >> 21) | ($h[8] << 4)) & 0xff;
     270        $s[26] = ($h[8] >> 4) & 0xff;
     271        $s[27] = ($h[8] >> 12) & 0xff;
     272        $s[28] = (($h[8] >> 20) | ($h[9] << 6)) & 0xff;
     273        $s[29] = ($h[9] >> 2) & 0xff;
     274        $s[30] = ($h[9] >> 10) & 0xff;
     275        $s[31] = ($h[9] >> 18) & 0xff;
     276
     277        return self::intArrayToString($s);
     278    }
     279
     280    /**
     281     * Is a field element negative? (1 = yes, 0 = no. Used in calculations.)
     282     *
     283     * @param ParagonIE_Sodium_Core_Curve25519_Fe $f
     284     * @return int
     285     */
     286    public static function fe_isnegative(ParagonIE_Sodium_Core_Curve25519_Fe $f)
     287    {
     288        $str = self::fe_tobytes($f);
     289        return self::chrToInt($str[0]) & 1;
     290    }
     291
     292    /**
     293     * Returns 0 if this field element results in all NUL bytes.
     294     *
     295     * @param ParagonIE_Sodium_Core_Curve25519_Fe $f
     296     * @return bool
     297     */
     298    public static function fe_isnonzero(ParagonIE_Sodium_Core_Curve25519_Fe $f)
     299    {
     300        static $zero;
     301        if ($zero === null) {
     302            $zero = str_repeat("\x00", 32);
     303        }
     304        $str = self::fe_tobytes($f);
     305        return !self::verify_32($str, $zero);
     306    }
     307
     308    /**
     309     * Multiply two field elements
     310     *
     311     * h = f * g
     312     *
     313     * @param ParagonIE_Sodium_Core_Curve25519_Fe $f
     314     * @param ParagonIE_Sodium_Core_Curve25519_Fe $g
     315     * @return ParagonIE_Sodium_Core_Curve25519_Fe
     316     */
     317    public static function fe_mul(
     318        ParagonIE_Sodium_Core_Curve25519_Fe $f,
     319        ParagonIE_Sodium_Core_Curve25519_Fe $g
     320    ) {
     321        $f0 = $f[0];
     322        $f1 = $f[1];
     323        $f2 = $f[2];
     324        $f3 = $f[3];
     325        $f4 = $f[4];
     326        $f5 = $f[5];
     327        $f6 = $f[6];
     328        $f7 = $f[7];
     329        $f8 = $f[8];
     330        $f9 = $f[9];
     331        $g0 = $g[0];
     332        $g1 = $g[1];
     333        $g2 = $g[2];
     334        $g3 = $g[3];
     335        $g4 = $g[4];
     336        $g5 = $g[5];
     337        $g6 = $g[6];
     338        $g7 = $g[7];
     339        $g8 = $g[8];
     340        $g9 = $g[9];
     341        $g1_19 = 19 * $g1;
     342        $g2_19 = 19 * $g2;
     343        $g3_19 = 19 * $g3;
     344        $g4_19 = 19 * $g4;
     345        $g5_19 = 19 * $g5;
     346        $g6_19 = 19 * $g6;
     347        $g7_19 = 19 * $g7;
     348        $g8_19 = 19 * $g8;
     349        $g9_19 = 19 * $g9;
     350        $f1_2 = 2 * $f1;
     351        $f3_2 = 2 * $f3;
     352        $f5_2 = 2 * $f5;
     353        $f7_2 = 2 * $f7;
     354        $f9_2 = 2 * $f9;
     355        $f0g0    = $f0   * $g0;
     356        $f0g1    = $f0   * $g1;
     357        $f0g2    = $f0   * $g2;
     358        $f0g3    = $f0   * $g3;
     359        $f0g4    = $f0   * $g4;
     360        $f0g5    = $f0   * $g5;
     361        $f0g6    = $f0   * $g6;
     362        $f0g7    = $f0   * $g7;
     363        $f0g8    = $f0   * $g8;
     364        $f0g9    = $f0   * $g9;
     365        $f1g0    = $f1   * $g0;
     366        $f1g1_2  = $f1_2 * $g1;
     367        $f1g2    = $f1   * $g2;
     368        $f1g3_2  = $f1_2 * $g3;
     369        $f1g4    = $f1   * $g4;
     370        $f1g5_2  = $f1_2 * $g5;
     371        $f1g6    = $f1   * $g6;
     372        $f1g7_2  = $f1_2 * $g7;
     373        $f1g8    = $f1   * $g8;
     374        $f1g9_38 = $f1_2 * $g9_19;
     375        $f2g0    = $f2   * $g0;
     376        $f2g1    = $f2   * $g1;
     377        $f2g2    = $f2   * $g2;
     378        $f2g3    = $f2   * $g3;
     379        $f2g4    = $f2   * $g4;
     380        $f2g5    = $f2   * $g5;
     381        $f2g6    = $f2   * $g6;
     382        $f2g7    = $f2   * $g7;
     383        $f2g8_19 = $f2   * $g8_19;
     384        $f2g9_19 = $f2   * $g9_19;
     385        $f3g0    = $f3   * $g0;
     386        $f3g1_2  = $f3_2 * $g1;
     387        $f3g2    = $f3   * $g2;
     388        $f3g3_2  = $f3_2 * $g3;
     389        $f3g4    = $f3   * $g4;
     390        $f3g5_2  = $f3_2 * $g5;
     391        $f3g6    = $f3   * $g6;
     392        $f3g7_38 = $f3_2 * $g7_19;
     393        $f3g8_19 = $f3   * $g8_19;
     394        $f3g9_38 = $f3_2 * $g9_19;
     395        $f4g0    = $f4   * $g0;
     396        $f4g1    = $f4   * $g1;
     397        $f4g2    = $f4   * $g2;
     398        $f4g3    = $f4   * $g3;
     399        $f4g4    = $f4   * $g4;
     400        $f4g5    = $f4   * $g5;
     401        $f4g6_19 = $f4   * $g6_19;
     402        $f4g7_19 = $f4   * $g7_19;
     403        $f4g8_19 = $f4   * $g8_19;
     404        $f4g9_19 = $f4   * $g9_19;
     405        $f5g0    = $f5   * $g0;
     406        $f5g1_2  = $f5_2 * $g1;
     407        $f5g2    = $f5   * $g2;
     408        $f5g3_2  = $f5_2 * $g3;
     409        $f5g4    = $f5   * $g4;
     410        $f5g5_38 = $f5_2 * $g5_19;
     411        $f5g6_19 = $f5   * $g6_19;
     412        $f5g7_38 = $f5_2 * $g7_19;
     413        $f5g8_19 = $f5   * $g8_19;
     414        $f5g9_38 = $f5_2 * $g9_19;
     415        $f6g0    = $f6   * $g0;
     416        $f6g1    = $f6   * $g1;
     417        $f6g2    = $f6   * $g2;
     418        $f6g3    = $f6   * $g3;
     419        $f6g4_19 = $f6   * $g4_19;
     420        $f6g5_19 = $f6   * $g5_19;
     421        $f6g6_19 = $f6   * $g6_19;
     422        $f6g7_19 = $f6   * $g7_19;
     423        $f6g8_19 = $f6   * $g8_19;
     424        $f6g9_19 = $f6   * $g9_19;
     425        $f7g0    = $f7   * $g0;
     426        $f7g1_2  = $f7_2 * $g1;
     427        $f7g2    = $f7   * $g2;
     428        $f7g3_38 = $f7_2 * $g3_19;
     429        $f7g4_19 = $f7   * $g4_19;
     430        $f7g5_38 = $f7_2 * $g5_19;
     431        $f7g6_19 = $f7   * $g6_19;
     432        $f7g7_38 = $f7_2 * $g7_19;
     433        $f7g8_19 = $f7   * $g8_19;
     434        $f7g9_38 = $f7_2 * $g9_19;
     435        $f8g0    = $f8   * $g0;
     436        $f8g1    = $f8   * $g1;
     437        $f8g2_19 = $f8   * $g2_19;
     438        $f8g3_19 = $f8   * $g3_19;
     439        $f8g4_19 = $f8   * $g4_19;
     440        $f8g5_19 = $f8   * $g5_19;
     441        $f8g6_19 = $f8   * $g6_19;
     442        $f8g7_19 = $f8   * $g7_19;
     443        $f8g8_19 = $f8   * $g8_19;
     444        $f8g9_19 = $f8   * $g9_19;
     445        $f9g0    = $f9   * $g0;
     446        $f9g1_38 = $f9_2 * $g1_19;
     447        $f9g2_19 = $f9   * $g2_19;
     448        $f9g3_38 = $f9_2 * $g3_19;
     449        $f9g4_19 = $f9   * $g4_19;
     450        $f9g5_38 = $f9_2 * $g5_19;
     451        $f9g6_19 = $f9   * $g6_19;
     452        $f9g7_38 = $f9_2 * $g7_19;
     453        $f9g8_19 = $f9   * $g8_19;
     454        $f9g9_38 = $f9_2 * $g9_19;
     455        $h0 = $f0g0 + $f1g9_38 + $f2g8_19 + $f3g7_38 + $f4g6_19 + $f5g5_38 + $f6g4_19 + $f7g3_38 + $f8g2_19 + $f9g1_38;
     456        $h1 = $f0g1 + $f1g0    + $f2g9_19 + $f3g8_19 + $f4g7_19 + $f5g6_19 + $f6g5_19 + $f7g4_19 + $f8g3_19 + $f9g2_19;
     457        $h2 = $f0g2 + $f1g1_2  + $f2g0    + $f3g9_38 + $f4g8_19 + $f5g7_38 + $f6g6_19 + $f7g5_38 + $f8g4_19 + $f9g3_38;
     458        $h3 = $f0g3 + $f1g2    + $f2g1    + $f3g0    + $f4g9_19 + $f5g8_19 + $f6g7_19 + $f7g6_19 + $f8g5_19 + $f9g4_19;
     459        $h4 = $f0g4 + $f1g3_2  + $f2g2    + $f3g1_2  + $f4g0    + $f5g9_38 + $f6g8_19 + $f7g7_38 + $f8g6_19 + $f9g5_38;
     460        $h5 = $f0g5 + $f1g4    + $f2g3    + $f3g2    + $f4g1    + $f5g0    + $f6g9_19 + $f7g8_19 + $f8g7_19 + $f9g6_19;
     461        $h6 = $f0g6 + $f1g5_2  + $f2g4    + $f3g3_2  + $f4g2    + $f5g1_2  + $f6g0    + $f7g9_38 + $f8g8_19 + $f9g7_38;
     462        $h7 = $f0g7 + $f1g6    + $f2g5    + $f3g4    + $f4g3    + $f5g2    + $f6g1    + $f7g0    + $f8g9_19 + $f9g8_19;
     463        $h8 = $f0g8 + $f1g7_2  + $f2g6    + $f3g5_2  + $f4g4    + $f5g3_2  + $f6g2    + $f7g1_2  + $f8g0    + $f9g9_38;
     464        $h9 = $f0g9 + $f1g8    + $f2g7    + $f3g6    + $f4g5    + $f5g4    + $f6g3    + $f7g2    + $f8g1    + $f9g0   ;
     465
     466        $carry0 = ($h0 + (1<<25)) >> 26; $h1 += $carry0; $h0 -= $carry0 << 26;
     467        $carry4 = ($h4 + (1<<25)) >> 26; $h5 += $carry4; $h4 -= $carry4 << 26;
     468
     469        $carry1 = ($h1 + (1<<24)) >> 25; $h2 += $carry1; $h1 -= $carry1 << 25;
     470        $carry5 = ($h5 + (1<<24)) >> 25; $h6 += $carry5; $h5 -= $carry5 << 25;
     471
     472        $carry2 = ($h2 + (1<<25)) >> 26; $h3 += $carry2; $h2 -= $carry2 << 26;
     473        $carry6 = ($h6 + (1<<25)) >> 26; $h7 += $carry6; $h6 -= $carry6 << 26;
     474
     475        $carry3 = ($h3 + (1<<24)) >> 25; $h4 += $carry3; $h3 -= $carry3 << 25;
     476        $carry7 = ($h7 + (1<<24)) >> 25; $h8 += $carry7; $h7 -= $carry7 << 25;
     477
     478        $carry4 = ($h4 + (1<<25)) >> 26; $h5 += $carry4; $h4 -= $carry4 << 26;
     479        $carry8 = ($h8 + (1<<25)) >> 26; $h9 += $carry8; $h8 -= $carry8 << 26;
     480
     481        $carry9 = ($h9 + (1<<24)) >> 25; $h0 += $carry9 * 19; $h9 -= $carry9 << 25;
     482
     483        $carry0 = ($h0 + (1<<25)) >> 26; $h1 += $carry0; $h0 -= $carry0 << 26;
     484
     485        return ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
     486            array(
     487                (int) $h0,
     488                (int) $h1,
     489                (int) $h2,
     490                (int) $h3,
     491                (int) $h4,
     492                (int) $h5,
     493                (int) $h6,
     494                (int) $h7,
     495                (int) $h8,
     496                (int) $h9
     497            )
     498        );
     499    }
     500
     501    /**
     502     * Get the negative values for each piece of the field element.
     503     *
     504     * h = -f
     505     *
     506     * @param ParagonIE_Sodium_Core_Curve25519_Fe $f
     507     * @return ParagonIE_Sodium_Core_Curve25519_Fe
     508     */
     509    public static function fe_neg(ParagonIE_Sodium_Core_Curve25519_Fe $f)
     510    {
     511        $h = new ParagonIE_Sodium_Core_Curve25519_Fe();
     512        for ($i = 0; $i < 10; ++$i) {
     513            $h[$i] = -1 * $f[$i];
     514        }
     515        return $h;
     516    }
     517
     518    /**
     519     * Square a field element
     520     *
     521     * h = f * f
     522     *
     523     * @param ParagonIE_Sodium_Core_Curve25519_Fe $f
     524     * @return ParagonIE_Sodium_Core_Curve25519_Fe
     525     */
     526    public static function fe_sq(ParagonIE_Sodium_Core_Curve25519_Fe $f)
     527    {
     528        $f0 = (int) $f[0];
     529        $f1 = (int) $f[1];
     530        $f2 = (int) $f[2];
     531        $f3 = (int) $f[3];
     532        $f4 = (int) $f[4];
     533        $f5 = (int) $f[5];
     534        $f6 = (int) $f[6];
     535        $f7 = (int) $f[7];
     536        $f8 = (int) $f[8];
     537        $f9 = (int) $f[9];
     538
     539        $f0_2 = 2 * $f0;
     540        $f1_2 = 2 * $f1;
     541        $f2_2 = 2 * $f2;
     542        $f3_2 = 2 * $f3;
     543        $f4_2 = 2 * $f4;
     544        $f5_2 = 2 * $f5;
     545        $f6_2 = 2 * $f6;
     546        $f7_2 = 2 * $f7;
     547        $f5_38 = 38 * $f5;
     548        $f6_19 = 19 * $f6;
     549        $f7_38 = 38 * $f7;
     550        $f8_19 = 19 * $f8;
     551        $f9_38 = 38 * $f9;
     552        $f0f0    = $f0   * $f0;
     553        $f0f1_2  = $f0_2 * $f1;
     554        $f0f2_2  = $f0_2 * $f2;
     555        $f0f3_2  = $f0_2 * $f3;
     556        $f0f4_2  = $f0_2 * $f4;
     557        $f0f5_2  = $f0_2 * $f5;
     558        $f0f6_2  = $f0_2 * $f6;
     559        $f0f7_2  = $f0_2 * $f7;
     560        $f0f8_2  = $f0_2 * $f8;
     561        $f0f9_2  = $f0_2 * $f9;
     562        $f1f1_2  = $f1_2 * $f1;
     563        $f1f2_2  = $f1_2 * $f2;
     564        $f1f3_4  = $f1_2 * $f3_2;
     565        $f1f4_2  = $f1_2 * $f4;
     566        $f1f5_4  = $f1_2 * $f5_2;
     567        $f1f6_2  = $f1_2 * $f6;
     568        $f1f7_4  = $f1_2 * $f7_2;
     569        $f1f8_2  = $f1_2 * $f8;
     570        $f1f9_76 = $f1_2 * $f9_38;
     571        $f2f2    = $f2   * $f2;
     572        $f2f3_2  = $f2_2 * $f3;
     573        $f2f4_2  = $f2_2 * $f4;
     574        $f2f5_2  = $f2_2 * $f5;
     575        $f2f6_2  = $f2_2 * $f6;
     576        $f2f7_2  = $f2_2 * $f7;
     577        $f2f8_38 = $f2_2 * $f8_19;
     578        $f2f9_38 = $f2   * $f9_38;
     579        $f3f3_2  = $f3_2 * $f3;
     580        $f3f4_2  = $f3_2 * $f4;
     581        $f3f5_4  = $f3_2 * $f5_2;
     582        $f3f6_2  = $f3_2 * $f6;
     583        $f3f7_76 = $f3_2 * $f7_38;
     584        $f3f8_38 = $f3_2 * $f8_19;
     585        $f3f9_76 = $f3_2 * $f9_38;
     586        $f4f4    = $f4   * $f4;
     587        $f4f5_2  = $f4_2 * $f5;
     588        $f4f6_38 = $f4_2 * $f6_19;
     589        $f4f7_38 = $f4   * $f7_38;
     590        $f4f8_38 = $f4_2 * $f8_19;
     591        $f4f9_38 = $f4   * $f9_38;
     592        $f5f5_38 = $f5   * $f5_38;
     593        $f5f6_38 = $f5_2 * $f6_19;
     594        $f5f7_76 = $f5_2 * $f7_38;
     595        $f5f8_38 = $f5_2 * $f8_19;
     596        $f5f9_76 = $f5_2 * $f9_38;
     597        $f6f6_19 = $f6   * $f6_19;
     598        $f6f7_38 = $f6   * $f7_38;
     599        $f6f8_38 = $f6_2 * $f8_19;
     600        $f6f9_38 = $f6   * $f9_38;
     601        $f7f7_38 = $f7   * $f7_38;
     602        $f7f8_38 = $f7_2 * $f8_19;
     603        $f7f9_76 = $f7_2 * $f9_38;
     604        $f8f8_19 = $f8   * $f8_19;
     605        $f8f9_38 = $f8   * $f9_38;
     606        $f9f9_38 = $f9   * $f9_38;
     607        $h0 = $f0f0   + $f1f9_76 + $f2f8_38 + $f3f7_76 + $f4f6_38 + $f5f5_38;
     608        $h1 = $f0f1_2 + $f2f9_38 + $f3f8_38 + $f4f7_38 + $f5f6_38;
     609        $h2 = $f0f2_2 + $f1f1_2  + $f3f9_76 + $f4f8_38 + $f5f7_76 + $f6f6_19;
     610        $h3 = $f0f3_2 + $f1f2_2  + $f4f9_38 + $f5f8_38 + $f6f7_38;
     611        $h4 = $f0f4_2 + $f1f3_4  + $f2f2    + $f5f9_76 + $f6f8_38 + $f7f7_38;
     612        $h5 = $f0f5_2 + $f1f4_2  + $f2f3_2  + $f6f9_38 + $f7f8_38;
     613        $h6 = $f0f6_2 + $f1f5_4  + $f2f4_2  + $f3f3_2  + $f7f9_76 + $f8f8_19;
     614        $h7 = $f0f7_2 + $f1f6_2  + $f2f5_2  + $f3f4_2  + $f8f9_38;
     615        $h8 = $f0f8_2 + $f1f7_4  + $f2f6_2  + $f3f5_4  + $f4f4    + $f9f9_38;
     616        $h9 = $f0f9_2 + $f1f8_2  + $f2f7_2  + $f3f6_2  + $f4f5_2;
     617
     618        $carry0 = ($h0 + (1<<25)) >> 26; $h1 += $carry0; $h0 -= $carry0 << 26;
     619        $carry4 = ($h4 + (1<<25)) >> 26; $h5 += $carry4; $h4 -= $carry4 << 26;
     620
     621        $carry1 = ($h1 + (1<<24)) >> 25; $h2 += $carry1; $h1 -= $carry1 << 25;
     622        $carry5 = ($h5 + (1<<24)) >> 25; $h6 += $carry5; $h5 -= $carry5 << 25;
     623
     624        $carry2 = ($h2 + (1<<25)) >> 26; $h3 += $carry2; $h2 -= $carry2 << 26;
     625        $carry6 = ($h6 + (1<<25)) >> 26; $h7 += $carry6; $h6 -= $carry6 << 26;
     626
     627        $carry3 = ($h3 + (1<<24)) >> 25; $h4 += $carry3; $h3 -= $carry3 << 25;
     628        $carry7 = ($h7 + (1<<24)) >> 25; $h8 += $carry7; $h7 -= $carry7 << 25;
     629
     630        $carry4 = ($h4 + (1<<25)) >> 26; $h5 += $carry4; $h4 -= $carry4 << 26;
     631        $carry8 = ($h8 + (1<<25)) >> 26; $h9 += $carry8; $h8 -= $carry8 << 26;
     632
     633        $carry9 = ($h9 + (1<<24)) >> 25; $h0 += $carry9 * 19; $h9 -= $carry9 << 25;
     634
     635        $carry0 = ($h0 + (1<<25)) >> 26; $h1 += $carry0; $h0 -= $carry0 << 26;
     636
     637        return ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
     638            array(
     639                (int) $h0,
     640                (int) $h1,
     641                (int) $h2,
     642                (int) $h3,
     643                (int) $h4,
     644                (int) $h5,
     645                (int) $h6,
     646                (int) $h7,
     647                (int) $h8,
     648                (int) $h9
     649            )
     650        );
     651    }
     652
     653
     654    /**
     655     * Square and double a field element
     656     *
     657     * h = 2 * f * f
     658     *
     659     * @param ParagonIE_Sodium_Core_Curve25519_Fe $f
     660     * @return ParagonIE_Sodium_Core_Curve25519_Fe
     661     */
     662    public static function fe_sq2(ParagonIE_Sodium_Core_Curve25519_Fe $f)
     663    {
     664        $f0 = (int) $f[0];
     665        $f1 = (int) $f[1];
     666        $f2 = (int) $f[2];
     667        $f3 = (int) $f[3];
     668        $f4 = (int) $f[4];
     669        $f5 = (int) $f[5];
     670        $f6 = (int) $f[6];
     671        $f7 = (int) $f[7];
     672        $f8 = (int) $f[8];
     673        $f9 = (int) $f[9];
     674
     675        $f0_2 = 2 * $f0;
     676        $f1_2 = 2 * $f1;
     677        $f2_2 = 2 * $f2;
     678        $f3_2 = 2 * $f3;
     679        $f4_2 = 2 * $f4;
     680        $f5_2 = 2 * $f5;
     681        $f6_2 = 2 * $f6;
     682        $f7_2 = 2 * $f7;
     683        $f5_38 = 38 * $f5; /* 1.959375*2^30 */
     684        $f6_19 = 19 * $f6; /* 1.959375*2^30 */
     685        $f7_38 = 38 * $f7; /* 1.959375*2^30 */
     686        $f8_19 = 19 * $f8; /* 1.959375*2^30 */
     687        $f9_38 = 38 * $f9; /* 1.959375*2^30 */
     688        $f0f0 = $f0 * (int) $f0;
     689        $f0f1_2 = $f0_2 * (int) $f1;
     690        $f0f2_2 = $f0_2 * (int) $f2;
     691        $f0f3_2 = $f0_2 * (int) $f3;
     692        $f0f4_2 = $f0_2 * (int) $f4;
     693        $f0f5_2 = $f0_2 * (int) $f5;
     694        $f0f6_2 = $f0_2 * (int) $f6;
     695        $f0f7_2 = $f0_2 * (int) $f7;
     696        $f0f8_2 = $f0_2 * (int) $f8;
     697        $f0f9_2 = $f0_2 * (int) $f9;
     698        $f1f1_2 = $f1_2 * (int) $f1;
     699        $f1f2_2 = $f1_2 * (int) $f2;
     700        $f1f3_4 = $f1_2 * (int) $f3_2;
     701        $f1f4_2 = $f1_2 * (int) $f4;
     702        $f1f5_4 = $f1_2 * (int) $f5_2;
     703        $f1f6_2 = $f1_2 * (int) $f6;
     704        $f1f7_4 = $f1_2 * (int) $f7_2;
     705        $f1f8_2 = $f1_2 * (int) $f8;
     706        $f1f9_76 = $f1_2 * (int) $f9_38;
     707        $f2f2 = $f2 * (int) $f2;
     708        $f2f3_2 = $f2_2 * (int) $f3;
     709        $f2f4_2 = $f2_2 * (int) $f4;
     710        $f2f5_2 = $f2_2 * (int) $f5;
     711        $f2f6_2 = $f2_2 * (int) $f6;
     712        $f2f7_2 = $f2_2 * (int) $f7;
     713        $f2f8_38 = $f2_2 * (int) $f8_19;
     714        $f2f9_38 = $f2 * (int) $f9_38;
     715        $f3f3_2 = $f3_2 * (int) $f3;
     716        $f3f4_2 = $f3_2 * (int) $f4;
     717        $f3f5_4 = $f3_2 * (int) $f5_2;
     718        $f3f6_2 = $f3_2 * (int) $f6;
     719        $f3f7_76 = $f3_2 * (int) $f7_38;
     720        $f3f8_38 = $f3_2 * (int) $f8_19;
     721        $f3f9_76 = $f3_2 * (int) $f9_38;
     722        $f4f4 = $f4 * (int) $f4;
     723        $f4f5_2 = $f4_2 * (int) $f5;
     724        $f4f6_38 = $f4_2 * (int) $f6_19;
     725        $f4f7_38 = $f4 * (int) $f7_38;
     726        $f4f8_38 = $f4_2 * (int) $f8_19;
     727        $f4f9_38 = $f4 * (int) $f9_38;
     728        $f5f5_38 = $f5 * (int) $f5_38;
     729        $f5f6_38 = $f5_2 * (int) $f6_19;
     730        $f5f7_76 = $f5_2 * (int) $f7_38;
     731        $f5f8_38 = $f5_2 * (int) $f8_19;
     732        $f5f9_76 = $f5_2 * (int) $f9_38;
     733        $f6f6_19 = $f6 * (int) $f6_19;
     734        $f6f7_38 = $f6 * (int) $f7_38;
     735        $f6f8_38 = $f6_2 * (int) $f8_19;
     736        $f6f9_38 = $f6 * (int) $f9_38;
     737        $f7f7_38 = $f7 * (int) $f7_38;
     738        $f7f8_38 = $f7_2 * (int) $f8_19;
     739        $f7f9_76 = $f7_2 * (int) $f9_38;
     740        $f8f8_19 = $f8 * (int) $f8_19;
     741        $f8f9_38 = $f8 * (int) $f9_38;
     742        $f9f9_38 = $f9 * (int) $f9_38;
     743
     744        $h0 = (int) ($f0f0 + $f1f9_76 + $f2f8_38 + $f3f7_76 + $f4f6_38 + $f5f5_38);
     745        $h1 = (int) ($f0f1_2 + $f2f9_38 + $f3f8_38 + $f4f7_38 + $f5f6_38);
     746        $h2 = (int) ($f0f2_2 + $f1f1_2  + $f3f9_76 + $f4f8_38 + $f5f7_76 + $f6f6_19);
     747        $h3 = (int) ($f0f3_2 + $f1f2_2  + $f4f9_38 + $f5f8_38 + $f6f7_38);
     748        $h4 = (int) ($f0f4_2 + $f1f3_4  + $f2f2    + $f5f9_76 + $f6f8_38 + $f7f7_38);
     749        $h5 = (int) ($f0f5_2 + $f1f4_2  + $f2f3_2  + $f6f9_38 + $f7f8_38);
     750        $h6 = (int) ($f0f6_2 + $f1f5_4  + $f2f4_2  + $f3f3_2  + $f7f9_76 + $f8f8_19);
     751        $h7 = (int) ($f0f7_2 + $f1f6_2  + $f2f5_2  + $f3f4_2  + $f8f9_38);
     752        $h8 = (int) ($f0f8_2 + $f1f7_4  + $f2f6_2  + $f3f5_4  + $f4f4    + $f9f9_38);
     753        $h9 = (int) ($f0f9_2 + $f1f8_2  + $f2f7_2  + $f3f6_2  + $f4f5_2);
     754
     755        $h0 = (int) ($h0 + $h0);
     756        $h1 = (int) ($h1 + $h1);
     757        $h2 = (int) ($h2 + $h2);
     758        $h3 = (int) ($h3 + $h3);
     759        $h4 = (int) ($h4 + $h4);
     760        $h5 = (int) ($h5 + $h5);
     761        $h6 = (int) ($h6 + $h6);
     762        $h7 = (int) ($h7 + $h7);
     763        $h8 = (int) ($h8 + $h8);
     764        $h9 = (int) ($h9 + $h9);
     765
     766        $carry0 = ($h0 + (1<<25)) >> 26; $h1 += $carry0; $h0 -= $carry0 << 26;
     767        $carry4 = ($h4 + (1<<25)) >> 26; $h5 += $carry4; $h4 -= $carry4 << 26;
     768
     769        $carry1 = ($h1 + (1<<24)) >> 25; $h2 += $carry1; $h1 -= $carry1 << 25;
     770        $carry5 = ($h5 + (1<<24)) >> 25; $h6 += $carry5; $h5 -= $carry5 << 25;
     771
     772        $carry2 = ($h2 + (1<<25)) >> 26; $h3 += $carry2; $h2 -= $carry2 << 26;
     773        $carry6 = ($h6 + (1<<25)) >> 26; $h7 += $carry6; $h6 -= $carry6 << 26;
     774
     775        $carry3 = ($h3 + (1<<24)) >> 25; $h4 += $carry3; $h3 -= $carry3 << 25;
     776        $carry7 = ($h7 + (1<<24)) >> 25; $h8 += $carry7; $h7 -= $carry7 << 25;
     777
     778        $carry4 = ($h4 + (1<<25)) >> 26; $h5 += $carry4; $h4 -= $carry4 << 26;
     779        $carry8 = ($h8 + (1<<25)) >> 26; $h9 += $carry8; $h8 -= $carry8 << 26;
     780
     781        $carry9 = ($h9 + (1<<24)) >> 25; $h0 += $carry9 * 19; $h9 -= $carry9 << 25;
     782
     783        $carry0 = ($h0 + (1<<25)) >> 26; $h1 += $carry0; $h0 -= $carry0 << 26;
     784
     785        return ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
     786            array(
     787                (int) $h0,
     788                (int) $h1,
     789                (int) $h2,
     790                (int) $h3,
     791                (int) $h4,
     792                (int) $h5,
     793                (int) $h6,
     794                (int) $h7,
     795                (int) $h8,
     796                (int) $h9
     797            )
     798        );
     799    }
     800
     801    /**
     802     * @param ParagonIE_Sodium_Core_Curve25519_Fe $Z
     803     * @return ParagonIE_Sodium_Core_Curve25519_Fe
     804     */
     805    public static function fe_invert(ParagonIE_Sodium_Core_Curve25519_Fe $Z)
     806    {
     807        $z = clone $Z;
     808        $t0 = self::fe_sq($z);
     809        $t1 = self::fe_sq($t0);
     810        $t1 = self::fe_sq($t1);
     811        $t1 = self::fe_mul($z, $t1);
     812        $t0 = self::fe_mul($t0, $t1);
     813        $t2 = self::fe_sq($t0);
     814        $t1 = self::fe_mul($t1, $t2);
     815        $t2 = self::fe_sq($t1);
     816        for ($i = 1; $i < 5; ++$i) {
     817            $t2 = self::fe_sq($t2);
     818        }
     819        $t1 = self::fe_mul($t2, $t1);
     820        $t2 = self::fe_sq($t1);
     821        for ($i = 1; $i < 10; ++$i) {
     822            $t2 = self::fe_sq($t2);
     823        }
     824        $t2 = self::fe_mul($t2, $t1);
     825        $t3 = self::fe_sq($t2);
     826        for ($i = 1; $i < 20; ++$i) {
     827            $t3 = self::fe_sq($t3);
     828        }
     829        $t2 = self::fe_mul($t3, $t2);
     830        $t2 = self::fe_sq($t2);
     831        for ($i = 1; $i < 10; ++$i) {
     832            $t2 = self::fe_sq($t2);
     833        }
     834        $t1 = self::fe_mul($t2, $t1);
     835        $t2 = self::fe_sq($t1);
     836        for ($i = 1; $i < 50; ++$i) {
     837            $t2 = self::fe_sq($t2);
     838        }
     839        $t2 = self::fe_mul($t2, $t1);
     840        $t3 = self::fe_sq($t2);
     841        for ($i = 1; $i < 100; ++$i) {
     842            $t3 = self::fe_sq($t3);
     843        }
     844        $t2 = self::fe_mul($t3, $t2);
     845        $t2 = self::fe_sq($t2);
     846        for ($i = 1; $i < 50; ++$i) {
     847            $t2 = self::fe_sq($t2);
     848        }
     849        $t1 = self::fe_mul($t2, $t1);
     850        $t1 = self::fe_sq($t1);
     851        for ($i = 1; $i < 5; ++$i) {
     852            $t1 = self::fe_sq($t1);
     853        }
     854        return self::fe_mul($t1, $t0);
     855    }
     856
     857    /**
     858     * @ref https://github.com/jedisct1/libsodium/blob/68564326e1e9dc57ef03746f85734232d20ca6fb/src/libsodium/crypto_core/curve25519/ref10/curve25519_ref10.c#L1054-L1106
     859     *
     860     * @param ParagonIE_Sodium_Core_Curve25519_Fe $z
     861     * @return ParagonIE_Sodium_Core_Curve25519_Fe
     862     */
     863    public static function fe_pow22523(ParagonIE_Sodium_Core_Curve25519_Fe $z)
     864    {
     865        # fe_sq(t0, z);
     866        # fe_sq(t1, t0);
     867        # fe_sq(t1, t1);
     868        # fe_mul(t1, z, t1);
     869        # fe_mul(t0, t0, t1);
     870        # fe_sq(t0, t0);
     871        # fe_mul(t0, t1, t0);
     872        # fe_sq(t1, t0);
     873        $t0 = self::fe_sq($z);
     874        $t1 = self::fe_sq($t0);
     875        $t1 = self::fe_sq($t1);
     876        $t1 = self::fe_mul($z, $t1);
     877        $t0 = self::fe_mul($t0, $t1);
     878        $t0 = self::fe_sq($t0);
     879        $t0 = self::fe_mul($t1, $t0);
     880        $t1 = self::fe_sq($t0);
     881
     882        # for (i = 1; i < 5; ++i) {
     883        #     fe_sq(t1, t1);
     884        # }
     885        for ($i = 1; $i < 5; ++$i) {
     886            $t1 = self::fe_sq($t1);
     887        }
     888
     889        # fe_mul(t0, t1, t0);
     890        # fe_sq(t1, t0);
     891        $t0 = self::fe_mul($t1, $t0);
     892        $t1 = self::fe_sq($t0);
     893
     894        # for (i = 1; i < 10; ++i) {
     895        #     fe_sq(t1, t1);
     896        # }
     897        for ($i = 1; $i < 10; ++$i) {
     898            $t1 = self::fe_sq($t1);
     899        }
     900
     901        # fe_mul(t1, t1, t0);
     902        # fe_sq(t2, t1);
     903        $t1 = self::fe_mul($t1, $t0);
     904        $t2 = self::fe_sq($t1);
     905
     906        # for (i = 1; i < 20; ++i) {
     907        #     fe_sq(t2, t2);
     908        # }
     909        for ($i = 1; $i < 20; ++$i) {
     910            $t2 = self::fe_sq($t2);
     911        }
     912
     913        # fe_mul(t1, t2, t1);
     914        # fe_sq(t1, t1);
     915        $t1 = self::fe_mul($t2, $t1);
     916        $t1 = self::fe_sq($t1);
     917
     918        # for (i = 1; i < 10; ++i) {
     919        #     fe_sq(t1, t1);
     920        # }
     921        for ($i = 1; $i < 10; ++$i) {
     922            $t1 = self::fe_sq($t1);
     923        }
     924
     925        # fe_mul(t0, t1, t0);
     926        # fe_sq(t1, t0);
     927        $t0 = self::fe_mul($t1, $t0);
     928        $t1 = self::fe_sq($t0);
     929
     930        # for (i = 1; i < 50; ++i) {
     931        #     fe_sq(t1, t1);
     932        # }
     933        for ($i = 1; $i < 50; ++$i) {
     934            $t1 = self::fe_sq($t1);
     935        }
     936
     937        # fe_mul(t1, t1, t0);
     938        # fe_sq(t2, t1);
     939        $t1 = self::fe_mul($t1, $t0);
     940        $t2 = self::fe_sq($t1);
     941
     942        # for (i = 1; i < 100; ++i) {
     943        #     fe_sq(t2, t2);
     944        # }
     945        for ($i = 1; $i < 100; ++$i) {
     946            $t2 = self::fe_sq($t2);
     947        }
     948
     949        # fe_mul(t1, t2, t1);
     950        # fe_sq(t1, t1);
     951        $t1 = self::fe_mul($t2, $t1);
     952        $t1 = self::fe_sq($t1);
     953
     954        # for (i = 1; i < 50; ++i) {
     955        #     fe_sq(t1, t1);
     956        # }
     957        for ($i = 1; $i < 50; ++$i) {
     958            $t1 = self::fe_sq($t1);
     959        }
     960
     961        # fe_mul(t0, t1, t0);
     962        # fe_sq(t0, t0);
     963        # fe_sq(t0, t0);
     964        # fe_mul(out, t0, z);
     965        $t0 = self::fe_mul($t1, $t0);
     966        $t0 = self::fe_sq($t0);
     967        $t0 = self::fe_sq($t0);
     968        return self::fe_mul($t0, $z);
     969    }
     970
     971    /**
     972     * Subtract two field elements.
     973     *
     974     * h = f - g
     975     *
     976     * Preconditions:
     977     * |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
     978     * |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
     979     *
     980     * Postconditions:
     981     * |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
     982     *
     983     * @param ParagonIE_Sodium_Core_Curve25519_Fe $f
     984     * @param ParagonIE_Sodium_Core_Curve25519_Fe $g
     985     * @return ParagonIE_Sodium_Core_Curve25519_Fe
     986     */
     987    public static function fe_sub(ParagonIE_Sodium_Core_Curve25519_Fe $f, ParagonIE_Sodium_Core_Curve25519_Fe $g)
     988    {
     989        return ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(
     990            array(
     991                (int) ($f[0] - $g[0]),
     992                (int) ($f[1] - $g[1]),
     993                (int) ($f[2] - $g[2]),
     994                (int) ($f[3] - $g[3]),
     995                (int) ($f[4] - $g[4]),
     996                (int) ($f[5] - $g[5]),
     997                (int) ($f[6] - $g[6]),
     998                (int) ($f[7] - $g[7]),
     999                (int) ($f[8] - $g[8]),
     1000                (int) ($f[9] - $g[9])
     1001            )
     1002        );
     1003    }
     1004
     1005    /**
     1006     * Add two group elements.
     1007     *
     1008     * r = p + q
     1009     *
     1010     * @param ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p
     1011     * @param ParagonIE_Sodium_Core_Curve25519_Ge_Cached $q
     1012     * @return ParagonIE_Sodium_Core_Curve25519_Ge_P1p1
     1013     */
     1014    public static function ge_add(
     1015        ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p,
     1016        ParagonIE_Sodium_Core_Curve25519_Ge_Cached $q
     1017    ) {
     1018        $r = new ParagonIE_Sodium_Core_Curve25519_Ge_P1p1();
     1019        $r->X = self::fe_add($p->Y, $p->X);
     1020        $r->Y = self::fe_sub($p->Y, $p->X);
     1021        $r->Z = self::fe_mul($r->X, $q->YplusX);
     1022        $r->Y = self::fe_mul($r->Y, $q->YminusX);
     1023        $r->T = self::fe_mul($q->T2d, $p->T);
     1024        $r->X = self::fe_mul($p->Z, $q->Z);
     1025        $t0 = self::fe_add($r->X, $r->X);
     1026        $r->X = self::fe_sub($r->Z, $r->Y);
     1027        $r->Y = self::fe_add($r->Z, $r->Y);
     1028        $r->Z = self::fe_add($t0, $r->T);
     1029        $r->T = self::fe_sub($t0, $r->T);
     1030        return $r;
     1031    }
     1032
     1033    /**
     1034     * @ref https://github.com/jedisct1/libsodium/blob/157c4a80c13b117608aeae12178b2d38825f9f8f/src/libsodium/crypto_core/curve25519/ref10/curve25519_ref10.c#L1185-L1215
     1035     * @param string $a
     1036     * @return int[]
     1037     */
     1038    public static function slide($a)
     1039    {
     1040        if (self::strlen($a) < 256) {
     1041            if (self::strlen($a) < 16) {
     1042                $a = str_pad($a, 256, '0', STR_PAD_RIGHT);
     1043            }
     1044        }
     1045        $r = array();
     1046        for ($i = 0; $i < 256; ++$i) {
     1047            $r[$i] = 1 & (
     1048                    self::chrToInt($a[$i >> 3])
     1049                        >>
     1050                    ($i & 7)
     1051                );
     1052        }
     1053
     1054        for ($i = 0;$i < 256;++$i) {
     1055            if ($r[$i]) {
     1056                for ($b = 1;$b <= 6 && $i + $b < 256;++$b) {
     1057                    if ($r[$i + $b]) {
     1058                        if ($r[$i] + ($r[$i + $b] << $b) <= 15) {
     1059                            $r[$i] += $r[$i + $b] << $b;
     1060                            $r[$i + $b] = 0;
     1061                        } else if ($r[$i] - ($r[$i + $b] << $b) >= -15) {
     1062                            $r[$i] -= $r[$i + $b] << $b;
     1063                            for ($k = $i + $b; $k < 256; ++$k) {
     1064                                if (!$r[$k]) {
     1065                                    $r[$k] = 1;
     1066                                    break;
     1067                                }
     1068                                $r[$k] = 0;
     1069                            }
     1070                        } else {
     1071                            break;
     1072                        }
     1073                    }
     1074                }
     1075            }
     1076        }
     1077        return $r;
     1078    }
     1079
     1080    /**
     1081     * @param string $s
     1082     * @return ParagonIE_Sodium_Core_Curve25519_Ge_P3
     1083     */
     1084    public static function ge_frombytes_negate_vartime($s)
     1085    {
     1086        static $d = null;
     1087        if (!$d) {
     1088            $d = ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(self::$d);
     1089        }
     1090
     1091        # fe_frombytes(h->Y,s);
     1092        # fe_1(h->Z);
     1093        $h = new ParagonIE_Sodium_Core_Curve25519_Ge_P3(
     1094            self::fe_0(),
     1095            self::fe_frombytes($s),
     1096            self::fe_1()
     1097        );
     1098
     1099        # fe_sq(u,h->Y);
     1100        # fe_mul(v,u,d);
     1101        # fe_sub(u,u,h->Z);       /* u = y^2-1 */
     1102        # fe_add(v,v,h->Z);       /* v = dy^2+1 */
     1103        $u = self::fe_sq($h->Y);
     1104        $v = self::fe_mul($u, $d);
     1105        $u = self::fe_sub($u, $h->Z); /* u =  y^2 - 1 */
     1106        $v = self::fe_add($v, $h->Z); /* v = dy^2 + 1 */
     1107
     1108        # fe_sq(v3,v);
     1109        # fe_mul(v3,v3,v);        /* v3 = v^3 */
     1110        # fe_sq(h->X,v3);
     1111        # fe_mul(h->X,h->X,v);
     1112        # fe_mul(h->X,h->X,u);    /* x = uv^7 */
     1113        $v3 = self::fe_sq($v);
     1114        $v3 = self::fe_mul($v3, $v); /* v3 = v^3 */
     1115        $h->X = self::fe_sq($v3);
     1116        $h->X = self::fe_mul($h->X, $v);
     1117        $h->X = self::fe_mul($h->X, $u); /* x = uv^7 */
     1118
     1119        # fe_pow22523(h->X,h->X); /* x = (uv^7)^((q-5)/8) */
     1120        # fe_mul(h->X,h->X,v3);
     1121        # fe_mul(h->X,h->X,u);    /* x = uv^3(uv^7)^((q-5)/8) */
     1122        $h->X = self::fe_pow22523($h->X); /* x = (uv^7)^((q-5)/8) */
     1123        $h->X = self::fe_mul($h->X, $v3);
     1124        $h->X = self::fe_mul($h->X, $u); /* x = uv^3(uv^7)^((q-5)/8) */
     1125
     1126        # fe_sq(vxx,h->X);
     1127        # fe_mul(vxx,vxx,v);
     1128        # fe_sub(check,vxx,u);    /* vx^2-u */
     1129        $vxx = self::fe_sq($h->X);
     1130        $vxx = self::fe_mul($vxx, $v);
     1131        $check = self::fe_sub($vxx, $u); /* vx^2 - u */
     1132
     1133        # if (fe_isnonzero(check)) {
     1134        #     fe_add(check,vxx,u);  /* vx^2+u */
     1135        #     if (fe_isnonzero(check)) {
     1136        #         return -1;
     1137        #     }
     1138        #     fe_mul(h->X,h->X,sqrtm1);
     1139        # }
     1140        if (self::fe_isnonzero($check)) {
     1141            $check = self::fe_add($vxx, $u); /* vx^2 + u */
     1142            if (self::fe_isnonzero($check)) {
     1143                throw new RangeException('Internal check failed.');
     1144            }
     1145            $h->X = self::fe_mul(
     1146                $h->X,
     1147                ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(self::$sqrtm1)
     1148            );
     1149        }
     1150
     1151        # if (fe_isnegative(h->X) == (s[31] >> 7)) {
     1152        #     fe_neg(h->X,h->X);
     1153        # }
     1154        $i = self::chrToInt($s[31]);
     1155        if (self::fe_isnegative($h->X) === ($i >> 7)) {
     1156            $h->X = self::fe_neg($h->X);
     1157        }
     1158
     1159        # fe_mul(h->T,h->X,h->Y);
     1160        $h->T = self::fe_mul($h->X, $h->Y);
     1161        return $h;
     1162    }
     1163
     1164    /**
     1165     * @param ParagonIE_Sodium_Core_Curve25519_Ge_P1p1 $R
     1166     * @param ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p
     1167     * @param ParagonIE_Sodium_Core_Curve25519_Ge_Precomp $q
     1168     * @return ParagonIE_Sodium_Core_Curve25519_Ge_P1p1
     1169     */
     1170    public static function ge_madd(
     1171        ParagonIE_Sodium_Core_Curve25519_Ge_P1p1 $R,
     1172        ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p,
     1173        ParagonIE_Sodium_Core_Curve25519_Ge_Precomp $q
     1174    ) {
     1175        $r = clone $R;
     1176        $r->X = self::fe_add($p->Y, $p->X);
     1177        $r->Y = self::fe_sub($p->Y, $p->X);
     1178        $r->Z = self::fe_mul($r->X, $q->yplusx);
     1179        $r->Y = self::fe_mul($r->Y, $q->yminusx);
     1180        $r->T = self::fe_mul($q->xy2d, $p->T);
     1181        $t0 = self::fe_add(clone $p->Z, clone $p->Z);
     1182        $r->X = self::fe_sub($r->Z, $r->Y);
     1183        $r->Y = self::fe_add($r->Z, $r->Y);
     1184        $r->Z = self::fe_add($t0, $r->T);
     1185        $r->T = self::fe_sub($t0, $r->T);
     1186
     1187        return $r;
     1188    }
     1189
     1190    /**
     1191     * @param ParagonIE_Sodium_Core_Curve25519_Ge_P1p1 $R
     1192     * @param ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p
     1193     * @param ParagonIE_Sodium_Core_Curve25519_Ge_Precomp $q
     1194     * @return ParagonIE_Sodium_Core_Curve25519_Ge_P1p1
     1195     */
     1196    public static function ge_msub(
     1197        ParagonIE_Sodium_Core_Curve25519_Ge_P1p1 $R,
     1198        ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p,
     1199        ParagonIE_Sodium_Core_Curve25519_Ge_Precomp $q
     1200    ) {
     1201        $r = clone $R;
     1202
     1203        $r->X = self::fe_add($p->Y, $p->X);
     1204        $r->Y = self::fe_sub($p->Y, $p->X);
     1205        $r->Z = self::fe_mul($r->X, $q->yminusx);
     1206        $r->Y = self::fe_mul($r->Y, $q->yplusx);
     1207        $r->T = self::fe_mul($q->xy2d, $p->T);
     1208        $t0 = self::fe_add($p->Z, $p->Z);
     1209        $r->X = self::fe_sub($r->Z, $r->Y);
     1210        $r->Y = self::fe_add($r->Z, $r->Y);
     1211        $r->Z = self::fe_sub($t0, $r->T);
     1212        $r->T = self::fe_add($t0, $r->T);
     1213
     1214        return $r;
     1215    }
     1216
     1217    /**
     1218     * @param ParagonIE_Sodium_Core_Curve25519_Ge_P1p1 $p
     1219     * @return ParagonIE_Sodium_Core_Curve25519_Ge_P2
     1220     */
     1221    public static function ge_p1p1_to_p2(ParagonIE_Sodium_Core_Curve25519_Ge_P1p1 $p)
     1222    {
     1223        $r = new ParagonIE_Sodium_Core_Curve25519_Ge_P2();
     1224        $r->X = self::fe_mul($p->X, $p->T);
     1225        $r->Y = self::fe_mul($p->Y, $p->Z);
     1226        $r->Z = self::fe_mul($p->Z, $p->T);
     1227        return $r;
     1228    }
     1229
     1230    /**
     1231     * @param ParagonIE_Sodium_Core_Curve25519_Ge_P1p1 $p
     1232     * @return ParagonIE_Sodium_Core_Curve25519_Ge_P3
     1233     */
     1234    public static function ge_p1p1_to_p3(ParagonIE_Sodium_Core_Curve25519_Ge_P1p1 $p)
     1235    {
     1236        $r = new ParagonIE_Sodium_Core_Curve25519_Ge_P3();
     1237        $r->X = self::fe_mul($p->X, $p->T);
     1238        $r->Y = self::fe_mul($p->Y, $p->Z);
     1239        $r->Z = self::fe_mul($p->Z, $p->T);
     1240        $r->T = self::fe_mul($p->X, $p->Y);
     1241        return $r;
     1242    }
     1243
     1244    /**
     1245     * @return ParagonIE_Sodium_Core_Curve25519_Ge_P2
     1246     */
     1247    public static function ge_p2_0()
     1248    {
     1249        return new ParagonIE_Sodium_Core_Curve25519_Ge_P2(
     1250            self::fe_0(),
     1251            self::fe_1(),
     1252            self::fe_1()
     1253        );
     1254    }
     1255
     1256    /**
     1257     * @param ParagonIE_Sodium_Core_Curve25519_Ge_P2 $p
     1258     * @return ParagonIE_Sodium_Core_Curve25519_Ge_P1p1
     1259     */
     1260    public static function ge_p2_dbl(ParagonIE_Sodium_Core_Curve25519_Ge_P2 $p)
     1261    {
     1262        $r = new ParagonIE_Sodium_Core_Curve25519_Ge_P1p1();
     1263
     1264        $r->X = self::fe_sq($p->X);
     1265        $r->Z = self::fe_sq($p->Y);
     1266        $r->T = self::fe_sq2($p->Z);
     1267        $r->Y = self::fe_add($p->X, $p->Y);
     1268        $t0 = self::fe_sq($r->Y);
     1269        $r->Y = self::fe_add($r->Z, $r->X);
     1270        $r->Z = self::fe_sub($r->Z, $r->X);
     1271        $r->X = self::fe_sub($t0, $r->Y);
     1272        $r->T = self::fe_sub($r->T, $r->Z);
     1273
     1274        return $r;
     1275    }
     1276
     1277    /**
     1278     * @return ParagonIE_Sodium_Core_Curve25519_Ge_P3
     1279     */
     1280    public static function ge_p3_0()
     1281    {
     1282        return new ParagonIE_Sodium_Core_Curve25519_Ge_P3(
     1283            self::fe_0(),
     1284            self::fe_1(),
     1285            self::fe_1(),
     1286            self::fe_0()
     1287        );
     1288    }
     1289
     1290    /**
     1291     * @param ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p
     1292     * @return ParagonIE_Sodium_Core_Curve25519_Ge_Cached
     1293     */
     1294    public static function ge_p3_to_cached(ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p)
     1295    {
     1296        static $d2 = null;
     1297        if ($d2 === null) {
     1298            $d2 = ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(self::$d2);
     1299        }
     1300        $r = new ParagonIE_Sodium_Core_Curve25519_Ge_Cached();
     1301        $r->YplusX = self::fe_add($p->Y, $p->X);
     1302        $r->YminusX = self::fe_sub($p->Y, $p->X);
     1303        $r->Z = self::fe_copy($p->Z);
     1304        $r->T2d = self::fe_mul($p->T, $d2);
     1305        return $r;
     1306    }
     1307
     1308    /**
     1309     * @param ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p
     1310     * @return ParagonIE_Sodium_Core_Curve25519_Ge_P2
     1311     */
     1312    public static function ge_p3_to_p2(ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p)
     1313    {
     1314        return new ParagonIE_Sodium_Core_Curve25519_Ge_P2(
     1315            $p->X,
     1316            $p->Y,
     1317            $p->Z
     1318        );
     1319    }
     1320
     1321    /**
     1322     * @param ParagonIE_Sodium_Core_Curve25519_Ge_P3 $h
     1323     * @return string
     1324     */
     1325    public static function ge_p3_tobytes(ParagonIE_Sodium_Core_Curve25519_Ge_P3 $h)
     1326    {
     1327        $recip = self::fe_invert($h->Z);
     1328        $x = self::fe_mul($h->X, $recip);
     1329        $y = self::fe_mul($h->Y, $recip);
     1330        $s = self::fe_tobytes($y);
     1331        $s[31] = self::intToChr(
     1332            self::chrToInt($s[31]) ^ (self::fe_isnegative($x) << 7)
     1333        );
     1334        return $s;
     1335    }
     1336
     1337    /**
     1338     * @param ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p
     1339     * @return ParagonIE_Sodium_Core_Curve25519_Ge_P1p1
     1340     */
     1341    public static function ge_p3_dbl(ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p)
     1342    {
     1343        $q = self::ge_p3_to_p2($p);
     1344        return self::ge_p2_dbl($q);
     1345    }
     1346
     1347    /**
     1348     * @return ParagonIE_Sodium_Core_Curve25519_Ge_Precomp
     1349     */
     1350    public static function ge_precomp_0()
     1351    {
     1352        return new ParagonIE_Sodium_Core_Curve25519_Ge_Precomp(
     1353            self::fe_1(),
     1354            self::fe_1(),
     1355            self::fe_0()
     1356        );
     1357    }
     1358
     1359    /**
     1360     * @param int $b
     1361     * @param int $c
     1362     * @return int
     1363     */
     1364    public static function equal($b, $c)
     1365    {
     1366        return (($b ^ $c) - 1 & 0xffffffff) >> 31;
     1367    }
     1368
     1369    /**
     1370     * @param string $char
     1371     * @return int (1 = yes, 0 = no)
     1372     */
     1373    public static function negative($char)
     1374    {
     1375        if (is_int($char)) {
     1376            return $char < 0 ? 1 : 0;
     1377        }
     1378        $x = self::chrToInt(self::substr($char, 0, 1));
     1379        if (PHP_INT_SIZE === 8) {
     1380            return $x >> 63;
     1381        }
     1382        return $x >> 31;
     1383    }
     1384
     1385    /**
     1386     * Conditional move
     1387     *
     1388     * @param ParagonIE_Sodium_Core_Curve25519_Ge_Precomp $t
     1389     * @param ParagonIE_Sodium_Core_Curve25519_Ge_Precomp $u
     1390     * @param int $b
     1391     * @return ParagonIE_Sodium_Core_Curve25519_Ge_Precomp
     1392     */
     1393    public static function cmov(
     1394        ParagonIE_Sodium_Core_Curve25519_Ge_Precomp $t,
     1395        ParagonIE_Sodium_Core_Curve25519_Ge_Precomp $u,
     1396        $b
     1397    ) {
     1398        if (!is_int($b)) {
     1399            throw new InvalidArgumentException('Expected an integer.');
     1400        }
     1401        return new ParagonIE_Sodium_Core_Curve25519_Ge_Precomp(
     1402            self::fe_cmov($t->yplusx, $u->yplusx, $b),
     1403            self::fe_cmov($t->yminusx, $u->yminusx, $b),
     1404            self::fe_cmov($t->xy2d, $u->xy2d, $b)
     1405        );
     1406    }
     1407
     1408    /**
     1409     * @param int $pos
     1410     * @param int $b
     1411     * @return ParagonIE_Sodium_Core_Curve25519_Ge_Precomp
     1412     */
     1413    public static function ge_select($pos = 0, $b = 0)
     1414    {
     1415        static $base = null;
     1416        if ($base === null) {
     1417            $base = array();
     1418            foreach (self::$base as $i => $bas) {
     1419                for ($j = 0; $j < 8; ++$j) {
     1420                    $base[$i][$j] = new ParagonIE_Sodium_Core_Curve25519_Ge_Precomp(
     1421                        ParagonIE_Sodium_Core_Curve25519_Fe::fromArray($bas[$j][0]),
     1422                        ParagonIE_Sodium_Core_Curve25519_Fe::fromArray($bas[$j][1]),
     1423                        ParagonIE_Sodium_Core_Curve25519_Fe::fromArray($bas[$j][2])
     1424                    );
     1425                }
     1426            }
     1427        }
     1428        if (!is_int($pos)) {
     1429            throw new InvalidArgumentException('Position must be an integer');
     1430        }
     1431        if ($pos < 0 || $pos > 31) {
     1432            throw new RangeException('Position is out of range [0, 31]');
     1433        }
     1434
     1435        $bnegative = self::negative($b);
     1436        $babs = $b - (((-$bnegative) & $b) << 1);
     1437
     1438        $t = self::ge_precomp_0();
     1439        for ($i = 0; $i < 8; ++$i) {
     1440            $t = self::cmov(
     1441                $t,
     1442                $base[$pos][$i],
     1443                self::equal($babs, $i + 1)
     1444            );
     1445        }
     1446        $minusT = new ParagonIE_Sodium_Core_Curve25519_Ge_Precomp(
     1447            self::fe_copy($t->yminusx),
     1448            self::fe_copy($t->yplusx),
     1449            self::fe_neg($t->xy2d)
     1450        );
     1451        return self::cmov($t, $minusT, $bnegative);
     1452    }
     1453
     1454    /**
     1455     * Subtract two group elements.
     1456     *
     1457     * r = p - q
     1458     *
     1459     * @param ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p
     1460     * @param ParagonIE_Sodium_Core_Curve25519_Ge_Cached $q
     1461     * @return ParagonIE_Sodium_Core_Curve25519_Ge_P1p1
     1462     */
     1463    public static function ge_sub(
     1464        ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p,
     1465        ParagonIE_Sodium_Core_Curve25519_Ge_Cached $q
     1466    ) {
     1467        $r = new ParagonIE_Sodium_Core_Curve25519_Ge_P1p1();
     1468
     1469        $r->X = self::fe_add($p->Y, $p->X);
     1470        $r->Y = self::fe_sub($p->Y, $p->X);
     1471        $r->Z = self::fe_mul($r->X, $q->YminusX);
     1472        $r->Y = self::fe_mul($r->Y, $q->YplusX);
     1473        $r->T = self::fe_mul($q->T2d, $p->T);
     1474        $r->X = self::fe_mul($p->Z, $q->Z);
     1475        $t0 = self::fe_add($r->X, $r->X);
     1476        $r->X = self::fe_sub($r->Z, $r->Y);
     1477        $r->Y = self::fe_add($r->Z, $r->Y);
     1478        $r->Z = self::fe_sub($t0, $r->T);
     1479        $r->T = self::fe_add($t0, $r->T);
     1480
     1481        return $r;
     1482    }
     1483
     1484    /**
     1485     * Convert a group element to a byte string.
     1486     *
     1487     * @param ParagonIE_Sodium_Core_Curve25519_Ge_P2 $h
     1488     * @return string
     1489     */
     1490    public static function ge_tobytes(ParagonIE_Sodium_Core_Curve25519_Ge_P2 $h)
     1491    {
     1492        $recip = self::fe_invert($h->Z);
     1493        $x = self::fe_mul($h->X, $recip);
     1494        $y = self::fe_mul($h->Y, $recip);
     1495        $s = self::fe_tobytes($y);
     1496        $s[31] = self::intToChr(
     1497            self::chrToInt($s[31]) ^ (self::fe_isnegative($x) << 7)
     1498        );
     1499        return $s;
     1500    }
     1501
     1502    /**
     1503     * @param string $a
     1504     * @param ParagonIE_Sodium_Core_Curve25519_Ge_P3 $A
     1505     * @param string $b
     1506     * @return ParagonIE_Sodium_Core_Curve25519_Ge_P2
     1507     */
     1508    public static function ge_double_scalarmult_vartime(
     1509        $a,
     1510        ParagonIE_Sodium_Core_Curve25519_Ge_P3 $A,
     1511        $b
     1512    ) {
     1513        /**
     1514         * @var ParagonIE_Sodium_Core_Curve25519_Ge_Cached[]
     1515         */
     1516        $Ai = array();
     1517
     1518        /**
     1519         * @var ParagonIE_Sodium_Core_Curve25519_Ge_Precomp[]
     1520         */
     1521        static $Bi = null;
     1522        if (!$Bi) {
     1523            for ($i = 0; $i < 8; ++$i) {
     1524                $Bi[$i] = new ParagonIE_Sodium_Core_Curve25519_Ge_Precomp(
     1525                    ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(self::$base2[$i][0]),
     1526                    ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(self::$base2[$i][1]),
     1527                    ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(self::$base2[$i][2])
     1528                );
     1529            }
     1530        }
     1531        for ($i = 0; $i < 8; ++$i) {
     1532            $Ai[$i] = new ParagonIE_Sodium_Core_Curve25519_Ge_Cached(
     1533                self::fe_0(),
     1534                self::fe_0(),
     1535                self::fe_0(),
     1536                self::fe_0()
     1537            );
     1538        }
     1539
     1540        # slide(aslide,a);
     1541        # slide(bslide,b);
     1542        $aslide = self::slide($a);
     1543        $bslide = self::slide($b);
     1544
     1545        # ge_p3_to_cached(&Ai[0],A);
     1546        # ge_p3_dbl(&t,A); ge_p1p1_to_p3(&A2,&t);
     1547        $Ai[0] = self::ge_p3_to_cached($A);
     1548        $t = self::ge_p3_dbl($A);
     1549        $A2 = self::ge_p1p1_to_p3($t);
     1550
     1551        # ge_add(&t,&A2,&Ai[0]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[1],&u);
     1552        # ge_add(&t,&A2,&Ai[1]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[2],&u);
     1553        # ge_add(&t,&A2,&Ai[2]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[3],&u);
     1554        # ge_add(&t,&A2,&Ai[3]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[4],&u);
     1555        # ge_add(&t,&A2,&Ai[4]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[5],&u);
     1556        # ge_add(&t,&A2,&Ai[5]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[6],&u);
     1557        # ge_add(&t,&A2,&Ai[6]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[7],&u);
     1558        for ($i = 0; $i < 7; ++$i) {
     1559            $t = self::ge_add($A2, $Ai[$i]);
     1560            $u = self::ge_p1p1_to_p3($t);
     1561            $Ai[$i + 1] = self::ge_p3_to_cached($u);
     1562        }
     1563
     1564        # ge_p2_0(r);
     1565        $r = self::ge_p2_0();
     1566
     1567        # for (i = 255;i >= 0;--i) {
     1568        #     if (aslide[i] || bslide[i]) break;
     1569        # }
     1570        for ($i = 255; $i >= 0; --$i) {
     1571            if ($aslide[$i] || $bslide[$i]) {
     1572                break;
     1573            }
     1574        }
     1575
     1576        # for (;i >= 0;--i) {
     1577        for (; $i >= 0; --$i) {
     1578            # ge_p2_dbl(&t,r);
     1579            $t = self::ge_p2_dbl($r);
     1580
     1581            # if (aslide[i] > 0) {
     1582            if ($aslide[$i] > 0) {
     1583                # ge_p1p1_to_p3(&u,&t);
     1584                # ge_add(&t,&u,&Ai[aslide[i]/2]);
     1585                $u = self::ge_p1p1_to_p3($t);
     1586                $t = self::ge_add(
     1587                    $u,
     1588                    $Ai[(int) floor($aslide[$i] / 2)]
     1589                );
     1590            # } else if (aslide[i] < 0) {
     1591            } elseif ($aslide[$i] < 0) {
     1592                # ge_p1p1_to_p3(&u,&t);
     1593                # ge_sub(&t,&u,&Ai[(-aslide[i])/2]);
     1594                $u = self::ge_p1p1_to_p3($t);
     1595                $t = self::ge_sub(
     1596                    $u,
     1597                    $Ai[(int) floor(-$aslide[$i] / 2)]
     1598                );
     1599            }
     1600
     1601            # if (bslide[i] > 0) {
     1602            if ($bslide[$i] > 0) {
     1603                # ge_p1p1_to_p3(&u,&t);
     1604                # ge_madd(&t,&u,&Bi[bslide[i]/2]);
     1605                $u = self::ge_p1p1_to_p3($t);
     1606                $t = self::ge_madd(
     1607                    $t,
     1608                    $u,
     1609                    $Bi[(int) floor($bslide[$i] / 2)]
     1610                );
     1611            # } else if (bslide[i] < 0) {
     1612            } elseif ($bslide[$i] < 0) {
     1613                # ge_p1p1_to_p3(&u,&t);
     1614                # ge_msub(&t,&u,&Bi[(-bslide[i])/2]);
     1615                $u = self::ge_p1p1_to_p3($t);
     1616                $t = self::ge_msub(
     1617                    $t,
     1618                    $u,
     1619                    $Bi[(int) floor(-$bslide[$i] / 2)]
     1620                );
     1621            }
     1622            # ge_p1p1_to_p2(r,&t);
     1623            $r = self::ge_p1p1_to_p2($t);
     1624        }
     1625        return $r;
     1626    }
     1627
     1628    /**
     1629     * @param string $a
     1630     * @return ParagonIE_Sodium_Core_Curve25519_Ge_P3
     1631     */
     1632    public static function ge_scalarmult_base($a)
     1633    {
     1634        $e = array();
     1635        $r = new ParagonIE_Sodium_Core_Curve25519_Ge_P1p1();
     1636
     1637        for ($i = 0; $i < 32; ++$i) {
     1638            $e[2 * $i] = self::chrToInt($a[$i]) & 15;
     1639            $e[2 * $i + 1] = (self::chrToInt($a[$i]) >> 4) & 15;
     1640        }
     1641
     1642        $carry = 0;
     1643        for ($i = 0; $i < 63; ++$i) {
     1644            $e[$i] += $carry;
     1645            $carry = $e[$i] + 8;
     1646            $carry >>= 4;
     1647            $e[$i] -= $carry << 4;
     1648        }
     1649        $e[63] += $carry;
     1650
     1651        $h = self::ge_p3_0();
     1652
     1653        for ($i = 1; $i < 64; $i += 2) {
     1654            $t = self::ge_select((int) floor($i / 2), $e[$i]);
     1655            $r = self::ge_madd($r, $h, $t);
     1656            $h = self::ge_p1p1_to_p3($r);
     1657        }
     1658
     1659        $r = self::ge_p3_dbl($h);
     1660
     1661        $s = self::ge_p1p1_to_p2($r);
     1662        $r = self::ge_p2_dbl($s);
     1663        $s = self::ge_p1p1_to_p2($r);
     1664        $r = self::ge_p2_dbl($s);
     1665        $s = self::ge_p1p1_to_p2($r);
     1666        $r = self::ge_p2_dbl($s);
     1667
     1668        $h = self::ge_p1p1_to_p3($r);
     1669
     1670        for ($i = 0; $i < 64; $i += 2) {
     1671            $t = self::ge_select((int) floor($i / 2), $e[$i]);
     1672            $r = self::ge_madd($r, $h, $t);
     1673            $h = self::ge_p1p1_to_p3($r);
     1674        }
     1675        return $h;
     1676    }
     1677
     1678    /**
     1679     * Calculates (ab + c) mod l
     1680     * where l = 2^252 + 27742317777372353535851937790883648493
     1681     *
     1682     * @param string $a
     1683     * @param string $b
     1684     * @param string $c
     1685     * @return string
     1686     */
     1687    public static function sc_muladd($a, $b, $c)
     1688    {
     1689        $a0 = 2097151 & self::load_3(self::substr($a, 0, 3));
     1690        $a1 = 2097151 & (self::load_4(self::substr($a, 2, 4)) >> 5);
     1691        $a2 = 2097151 & (self::load_3(self::substr($a, 5, 3)) >> 2);
     1692        $a3 = 2097151 & (self::load_4(self::substr($a, 7, 4)) >> 7);
     1693        $a4 = 2097151 & (self::load_4(self::substr($a, 10, 4)) >> 4);
     1694        $a5 = 2097151 & (self::load_3(self::substr($a, 13, 3)) >> 1);
     1695        $a6 = 2097151 & (self::load_4(self::substr($a, 15, 4)) >> 6);
     1696        $a7 = 2097151 & (self::load_3(self::substr($a, 18, 3)) >> 3);
     1697        $a8 = 2097151 & self::load_3(self::substr($a, 21, 3));
     1698        $a9 = 2097151 & (self::load_4(self::substr($a, 23, 4)) >> 5);
     1699        $a10 = 2097151 & (self::load_3(self::substr($a, 26, 3)) >> 2);
     1700        $a11 = (self::load_4(self::substr($a, 28, 4)) >> 7);
     1701        $b0 = 2097151 & self::load_3(self::substr($b, 0, 3));
     1702        $b1 = 2097151 & (self::load_4(self::substr($b, 2, 4)) >> 5);
     1703        $b2 = 2097151 & (self::load_3(self::substr($b, 5, 3)) >> 2);
     1704        $b3 = 2097151 & (self::load_4(self::substr($b, 7, 4)) >> 7);
     1705        $b4 = 2097151 & (self::load_4(self::substr($b, 10, 4)) >> 4);
     1706        $b5 = 2097151 & (self::load_3(self::substr($b, 13, 3)) >> 1);
     1707        $b6 = 2097151 & (self::load_4(self::substr($b, 15, 4)) >> 6);
     1708        $b7 = 2097151 & (self::load_3(self::substr($b, 18, 3)) >> 3);
     1709        $b8 = 2097151 & self::load_3(self::substr($b, 21, 3));
     1710        $b9 = 2097151 & (self::load_4(self::substr($b, 23, 4)) >> 5);
     1711        $b10 = 2097151 & (self::load_3(self::substr($b, 26, 3)) >> 2);
     1712        $b11 = (self::load_4(self::substr($b, 28, 4)) >> 7);
     1713        $c0 = 2097151 & self::load_3(self::substr($c, 0, 3));
     1714        $c1 = 2097151 & (self::load_4(self::substr($c, 2, 4)) >> 5);
     1715        $c2 = 2097151 & (self::load_3(self::substr($c, 5, 3)) >> 2);
     1716        $c3 = 2097151 & (self::load_4(self::substr($c, 7, 4)) >> 7);
     1717        $c4 = 2097151 & (self::load_4(self::substr($c, 10, 4)) >> 4);
     1718        $c5 = 2097151 & (self::load_3(self::substr($c, 13, 3)) >> 1);
     1719        $c6 = 2097151 & (self::load_4(self::substr($c, 15, 4)) >> 6);
     1720        $c7 = 2097151 & (self::load_3(self::substr($c, 18, 3)) >> 3);
     1721        $c8 = 2097151 & self::load_3(self::substr($c, 21, 3));
     1722        $c9 = 2097151 & (self::load_4(self::substr($c, 23, 4)) >> 5);
     1723        $c10 = 2097151 & (self::load_3(self::substr($c, 26, 3)) >> 2);
     1724        $c11 = (self::load_4(self::substr($c, 28, 4)) >> 7);
     1725
     1726        $s0 = $c0 + $a0 * $b0;
     1727        $s1 = $c1 + $a0 * $b1 + $a1 * $b0;
     1728        $s2 = $c2 + $a0 * $b2 + $a1 * $b1 + $a2 * $b0;
     1729        $s3 = $c3 + $a0 * $b3 + $a1 * $b2 + $a2 * $b1 + $a3 * $b0;
     1730        $s4 = $c4 + $a0 * $b4 + $a1 * $b3 + $a2 * $b2 + $a3 * $b1 + $a4 * $b0;
     1731        $s5 = $c5 + $a0 * $b5 + $a1 * $b4 + $a2 * $b3 + $a3 * $b2 + $a4 * $b1 + $a5 * $b0;
     1732        $s6 = $c6 + $a0 * $b6 + $a1 * $b5 + $a2 * $b4 + $a3 * $b3 + $a4 * $b2 + $a5 * $b1 + $a6 * $b0;
     1733        $s7 = $c7 + $a0 * $b7 + $a1 * $b6 + $a2 * $b5 + $a3 * $b4 + $a4 * $b3 + $a5 * $b2 + $a6 * $b1 + $a7 * $b0;
     1734        $s8 = $c8 + $a0 * $b8 + $a1 * $b7 + $a2 * $b6 + $a3 * $b5 + $a4 * $b4 + $a5 * $b3 + $a6 * $b2 + $a7 * $b1 + $a8 * $b0;
     1735        $s9 = $c9 + $a0 * $b9 + $a1 * $b8 + $a2 * $b7 + $a3 * $b6 + $a4 * $b5 + $a5 * $b4 + $a6 * $b3 + $a7 * $b2 + $a8 * $b1 + $a9 * $b0;
     1736        $s10 = $c10 + $a0 * $b10 + $a1 * $b9 + $a2 * $b8 + $a3 * $b7 + $a4 * $b6 + $a5 * $b5 + $a6 * $b4 + $a7 * $b3 + $a8 * $b2 + $a9 * $b1 + $a10 * $b0;
     1737        $s11 = $c11 + $a0 * $b11 + $a1 * $b10 + $a2 * $b9 + $a3 * $b8 + $a4 * $b7 + $a5 * $b6 + $a6 * $b5 + $a7 * $b4 + $a8 * $b3 + $a9 * $b2 + $a10 * $b1 + $a11 * $b0;
     1738        $s12 = $a1 * $b11 + $a2 * $b10 + $a3 * $b9 + $a4 * $b8 + $a5 * $b7 + $a6 * $b6 + $a7 * $b5 + $a8 * $b4 + $a9 * $b3 + $a10 * $b2 + $a11 * $b1;
     1739        $s13 = $a2 * $b11 + $a3 * $b10 + $a4 * $b9 + $a5 * $b8 + $a6 * $b7 + $a7 * $b6 + $a8 * $b5 + $a9 * $b4 + $a10 * $b3 + $a11 * $b2;
     1740        $s14 = $a3 * $b11 + $a4 * $b10 + $a5 * $b9 + $a6 * $b8 + $a7 * $b7 + $a8 * $b6 + $a9 * $b5 + $a10 * $b4 + $a11 * $b3;
     1741        $s15 = $a4 * $b11 + $a5 * $b10 + $a6 * $b9 + $a7 * $b8 + $a8 * $b7 + $a9 * $b6 + $a10 * $b5 + $a11 * $b4;
     1742        $s16 = $a5 * $b11 + $a6 * $b10 + $a7 * $b9 + $a8 * $b8 + $a9 * $b7 + $a10 * $b6 + $a11 * $b5;
     1743        $s17 = $a6 * $b11 + $a7 * $b10 + $a8 * $b9 + $a9 * $b8 + $a10 * $b7 + $a11 * $b6;
     1744        $s18 = $a7 * $b11 + $a8 * $b10 + $a9 * $b9 + $a10 * $b8 + $a11 * $b7;
     1745        $s19 = $a8 * $b11 + $a9 * $b10 + $a10 * $b9 + $a11 * $b8;
     1746        $s20 = $a9 * $b11 + $a10 * $b10 + $a11 * $b9;
     1747        $s21 = $a10 * $b11 + $a11 * $b10;
     1748        $s22 = $a11 * $b11;
     1749        $s23 = 0;
     1750
     1751
     1752        $carry0 = ($s0 + (1 << 20)) >> 21; $s1 += $carry0; $s0 -= $carry0 * (1 << 21);
     1753        $carry2 = ($s2 + (1 << 20)) >> 21; $s3 += $carry2; $s2 -= $carry2 * (1 << 21);
     1754        $carry4 = ($s4 + (1 << 20)) >> 21; $s5 += $carry4; $s4 -= $carry4 * (1 << 21);
     1755        $carry6 = ($s6 + (1 << 20)) >> 21; $s7 += $carry6; $s6 -= $carry6 * (1 << 21);
     1756        $carry8 = ($s8 + (1 << 20)) >> 21; $s9 += $carry8; $s8 -= $carry8 * (1 << 21);
     1757        $carry10 = ($s10 + (1 << 20)) >> 21; $s11 += $carry10; $s10 -= $carry10 * (1 << 21);
     1758        $carry12 = ($s12 + (1 << 20)) >> 21; $s13 += $carry12; $s12 -= $carry12 * (1 << 21);
     1759        $carry14 = ($s14 + (1 << 20)) >> 21; $s15 += $carry14; $s14 -= $carry14 * (1 << 21);
     1760        $carry16 = ($s16 + (1 << 20)) >> 21; $s17 += $carry16; $s16 -= $carry16 * (1 << 21);
     1761        $carry18 = ($s18 + (1 << 20)) >> 21; $s19 += $carry18; $s18 -= $carry18 * (1 << 21);
     1762        $carry20 = ($s20 + (1 << 20)) >> 21; $s21 += $carry20; $s20 -= $carry20 * (1 << 21);
     1763        $carry22 = ($s22 + (1 << 20)) >> 21; $s23 += $carry22; $s22 -= $carry22 * (1 << 21);
     1764
     1765        $carry1 = ($s1 + (1 << 20)) >> 21; $s2 += $carry1; $s1 -= $carry1 * (1 << 21);
     1766        $carry3 = ($s3 + (1 << 20)) >> 21; $s4 += $carry3; $s3 -= $carry3 * (1 << 21);
     1767        $carry5 = ($s5 + (1 << 20)) >> 21; $s6 += $carry5; $s5 -= $carry5 * (1 << 21);
     1768        $carry7 = ($s7 + (1 << 20)) >> 21; $s8 += $carry7; $s7 -= $carry7 * (1 << 21);
     1769        $carry9 = ($s9 + (1 << 20)) >> 21; $s10 += $carry9; $s9 -= $carry9 * (1 << 21);
     1770        $carry11 = ($s11 + (1 << 20)) >> 21; $s12 += $carry11; $s11 -= $carry11 * (1 << 21);
     1771        $carry13 = ($s13 + (1 << 20)) >> 21; $s14 += $carry13; $s13 -= $carry13 * (1 << 21);
     1772        $carry15 = ($s15 + (1 << 20)) >> 21; $s16 += $carry15; $s15 -= $carry15 * (1 << 21);
     1773        $carry17 = ($s17 + (1 << 20)) >> 21; $s18 += $carry17; $s17 -= $carry17 * (1 << 21);
     1774        $carry19 = ($s19 + (1 << 20)) >> 21; $s20 += $carry19; $s19 -= $carry19 * (1 << 21);
     1775        $carry21 = ($s21 + (1 << 20)) >> 21; $s22 += $carry21; $s21 -= $carry21 * (1 << 21);
     1776
     1777        $s11 += $s23 * 666643;
     1778        $s12 += $s23 * 470296;
     1779        $s13 += $s23 * 654183;
     1780        $s14 -= $s23 * 997805;
     1781        $s15 += $s23 * 136657;
     1782        $s16 -= $s23 * 683901;
     1783
     1784        $s10 += $s22 * 666643;
     1785        $s11 += $s22 * 470296;
     1786        $s12 += $s22 * 654183;
     1787        $s13 -= $s22 * 997805;
     1788        $s14 += $s22 * 136657;
     1789        $s15 -= $s22 * 683901;
     1790
     1791        $s9 += $s21 * 666643;
     1792        $s10 += $s21 * 470296;
     1793        $s11 += $s21 * 654183;
     1794        $s12 -= $s21 * 997805;
     1795        $s13 += $s21 * 136657;
     1796        $s14 -= $s21 * 683901;
     1797
     1798        $s8 += $s20 * 666643;
     1799        $s9 += $s20 * 470296;
     1800        $s10 += $s20 * 654183;
     1801        $s11 -= $s20 * 997805;
     1802        $s12 += $s20 * 136657;
     1803        $s13 -= $s20 * 683901;
     1804
     1805        $s7 += $s19 * 666643;
     1806        $s8 += $s19 * 470296;
     1807        $s9 += $s19 * 654183;
     1808        $s10 -= $s19 * 997805;
     1809        $s11 += $s19 * 136657;
     1810        $s12 -= $s19 * 683901;
     1811
     1812        $s6 += $s18 * 666643;
     1813        $s7 += $s18 * 470296;
     1814        $s8 += $s18 * 654183;
     1815        $s9 -= $s18 * 997805;
     1816        $s10 += $s18 * 136657;
     1817        $s11 -= $s18 * 683901;
     1818
     1819        $carry6 = ($s6 + (1 << 20)) >> 21; $s7 += $carry6; $s6 -= $carry6 * (1 << 21);
     1820        $carry8 = ($s8 + (1 << 20)) >> 21; $s9 += $carry8; $s8 -= $carry8 * (1 << 21);
     1821        $carry10 = ($s10 + (1 << 20)) >> 21; $s11 += $carry10; $s10 -= $carry10 * (1 << 21);
     1822        $carry12 = ($s12 + (1 << 20)) >> 21; $s13 += $carry12; $s12 -= $carry12 * (1 << 21);
     1823        $carry14 = ($s14 + (1 << 20)) >> 21; $s15 += $carry14; $s14 -= $carry14 * (1 << 21);
     1824        $carry16 = ($s16 + (1 << 20)) >> 21; $s17 += $carry16; $s16 -= $carry16 * (1 << 21);
     1825
     1826        $carry7 = ($s7 + (1 << 20)) >> 21; $s8 += $carry7; $s7 -= $carry7 * (1 << 21);
     1827        $carry9 = ($s9 + (1 << 20)) >> 21; $s10 += $carry9; $s9 -= $carry9 * (1 << 21);
     1828        $carry11 = ($s11 + (1 << 20)) >> 21; $s12 += $carry11; $s11 -= $carry11 * (1 << 21);
     1829        $carry13 = ($s13 + (1 << 20)) >> 21; $s14 += $carry13; $s13 -= $carry13 * (1 << 21);
     1830        $carry15 = ($s15 + (1 << 20)) >> 21; $s16 += $carry15; $s15 -= $carry15 * (1 << 21);
     1831
     1832        $s5 += $s17 * 666643;
     1833        $s6 += $s17 * 470296;
     1834        $s7 += $s17 * 654183;
     1835        $s8 -= $s17 * 997805;
     1836        $s9 += $s17 * 136657;
     1837        $s10 -= $s17 * 683901;
     1838
     1839        $s4 += $s16 * 666643;
     1840        $s5 += $s16 * 470296;
     1841        $s6 += $s16 * 654183;
     1842        $s7 -= $s16 * 997805;
     1843        $s8 += $s16 * 136657;
     1844        $s9 -= $s16 * 683901;
     1845
     1846        $s3 += $s15 * 666643;
     1847        $s4 += $s15 * 470296;
     1848        $s5 += $s15 * 654183;
     1849        $s6 -= $s15 * 997805;
     1850        $s7 += $s15 * 136657;
     1851        $s8 -= $s15 * 683901;
     1852
     1853        $s2 += $s14 * 666643;
     1854        $s3 += $s14 * 470296;
     1855        $s4 += $s14 * 654183;
     1856        $s5 -= $s14 * 997805;
     1857        $s6 += $s14 * 136657;
     1858        $s7 -= $s14 * 683901;
     1859
     1860        $s1 += $s13 * 666643;
     1861        $s2 += $s13 * 470296;
     1862        $s3 += $s13 * 654183;
     1863        $s4 -= $s13 * 997805;
     1864        $s5 += $s13 * 136657;
     1865        $s6 -= $s13 * 683901;
     1866
     1867        $s0 += $s12 * 666643;
     1868        $s1 += $s12 * 470296;
     1869        $s2 += $s12 * 654183;
     1870        $s3 -= $s12 * 997805;
     1871        $s4 += $s12 * 136657;
     1872        $s5 -= $s12 * 683901;
     1873        $s12 = 0;
     1874
     1875        $carry0 = ($s0 + (1 << 20)) >> 21; $s1 += $carry0; $s0 -= $carry0 * (1 << 21);
     1876        $carry2 = ($s2 + (1 << 20)) >> 21; $s3 += $carry2; $s2 -= $carry2 * (1 << 21);
     1877        $carry4 = ($s4 + (1 << 20)) >> 21; $s5 += $carry4; $s4 -= $carry4 * (1 << 21);
     1878        $carry6 = ($s6 + (1 << 20)) >> 21; $s7 += $carry6; $s6 -= $carry6 * (1 << 21);
     1879        $carry8 = ($s8 + (1 << 20)) >> 21; $s9 += $carry8; $s8 -= $carry8 * (1 << 21);
     1880        $carry10 = ($s10 + (1 << 20)) >> 21; $s11 += $carry10; $s10 -= $carry10 * (1 << 21);
     1881
     1882        $carry1 = ($s1 + (1 << 20)) >> 21; $s2 += $carry1; $s1 -= $carry1 * (1 << 21);
     1883        $carry3 = ($s3 + (1 << 20)) >> 21; $s4 += $carry3; $s3 -= $carry3 * (1 << 21);
     1884        $carry5 = ($s5 + (1 << 20)) >> 21; $s6 += $carry5; $s5 -= $carry5 * (1 << 21);
     1885        $carry7 = ($s7 + (1 << 20)) >> 21; $s8 += $carry7; $s7 -= $carry7 * (1 << 21);
     1886        $carry9 = ($s9 + (1 << 20)) >> 21; $s10 += $carry9; $s9 -= $carry9 * (1 << 21);
     1887        $carry11 = ($s11 + (1 << 20)) >> 21; $s12 += $carry11; $s11 -= $carry11 * (1 << 21);
     1888
     1889        $s0 += $s12 * 666643;
     1890        $s1 += $s12 * 470296;
     1891        $s2 += $s12 * 654183;
     1892        $s3 -= $s12 * 997805;
     1893        $s4 += $s12 * 136657;
     1894        $s5 -= $s12 * 683901;
     1895        $s12 = 0;
     1896
     1897        $carry0 = $s0 >> 21; $s1 += $carry0; $s0 -= $carry0 * (1 << 21);
     1898        $carry1 = $s1 >> 21; $s2 += $carry1; $s1 -= $carry1 * (1 << 21);
     1899        $carry2 = $s2 >> 21; $s3 += $carry2; $s2 -= $carry2 * (1 << 21);
     1900        $carry3 = $s3 >> 21; $s4 += $carry3; $s3 -= $carry3 * (1 << 21);
     1901        $carry4 = $s4 >> 21; $s5 += $carry4; $s4 -= $carry4 * (1 << 21);
     1902        $carry5 = $s5 >> 21; $s6 += $carry5; $s5 -= $carry5 * (1 << 21);
     1903        $carry6 = $s6 >> 21; $s7 += $carry6; $s6 -= $carry6 * (1 << 21);
     1904        $carry7 = $s7 >> 21; $s8 += $carry7; $s7 -= $carry7 * (1 << 21);
     1905        $carry8 = $s8 >> 21; $s9 += $carry8; $s8 -= $carry8 * (1 << 21);
     1906        $carry9 = $s9 >> 21; $s10 += $carry9; $s9 -= $carry9 * (1 << 21);
     1907        $carry10 = $s10 >> 21; $s11 += $carry10; $s10 -= $carry10 * (1 << 21);
     1908        $carry11 = $s11 >> 21; $s12 += $carry11; $s11 -= $carry11 * (1 << 21);
     1909
     1910
     1911        $s0 += $s12 * 666643;
     1912        $s1 += $s12 * 470296;
     1913        $s2 += $s12 * 654183;
     1914        $s3 -= $s12 * 997805;
     1915        $s4 += $s12 * 136657;
     1916        $s5 -= $s12 * 683901;
     1917
     1918        $carry0 = $s0 >> 21; $s1 += $carry0; $s0 -= $carry0 * (1 << 21);
     1919        $carry1 = $s1 >> 21; $s2 += $carry1; $s1 -= $carry1 * (1 << 21);
     1920        $carry2 = $s2 >> 21; $s3 += $carry2; $s2 -= $carry2 * (1 << 21);
     1921        $carry3 = $s3 >> 21; $s4 += $carry3; $s3 -= $carry3 * (1 << 21);
     1922        $carry4 = $s4 >> 21; $s5 += $carry4; $s4 -= $carry4 * (1 << 21);
     1923        $carry5 = $s5 >> 21; $s6 += $carry5; $s5 -= $carry5 * (1 << 21);
     1924        $carry6 = $s6 >> 21; $s7 += $carry6; $s6 -= $carry6 * (1 << 21);
     1925        $carry7 = $s7 >> 21; $s8 += $carry7; $s7 -= $carry7 * (1 << 21);
     1926        $carry8 = $s8 >> 21; $s9 += $carry8; $s8 -= $carry8 * (1 << 21);
     1927        $carry9 = $s9 >> 21; $s10 += $carry9; $s9 -= $carry9 * (1 << 21);
     1928        $carry10 = $s10 >> 21; $s11 += $carry10; $s10 -= $carry10 * (1 << 21);
     1929
     1930        return self::intArrayToString(
     1931            array(
     1932                0xff & ($s0 >> 0),
     1933                0xff & ($s0 >> 8),
     1934                0xff & (($s0 >> 16) | ($s1 * (1 << 5))),
     1935                0xff & ($s1 >> 3),
     1936                0xff & ($s1 >> 11),
     1937                0xff & (($s1 >> 19) | ($s2 * (1 << 2))),
     1938                0xff & ($s2 >> 6),
     1939                0xff & (($s2 >> 14) | ($s3 * (1 << 7))),
     1940                0xff & ($s3 >> 1),
     1941                0xff & ($s3 >> 9),
     1942                0xff & (($s3 >> 17) | ($s4 * (1 << 4))),
     1943                0xff & ($s4 >> 4),
     1944                0xff & ($s4 >> 12),
     1945                0xff & (($s4 >> 20) | ($s5 * (1 << 1))),
     1946                0xff & ($s5 >> 7),
     1947                0xff & (($s5 >> 15) | ($s6 * (1 << 6))),
     1948                0xff & ($s6 >> 2),
     1949                0xff & ($s6 >> 10),
     1950                0xff & (($s6 >> 18) | ($s7 * (1 << 3))),
     1951                0xff & ($s7 >> 5),
     1952                0xff & ($s7 >> 13),
     1953                0xff & ($s8 >> 0),
     1954                0xff & ($s8 >> 8),
     1955                0xff & (($s8 >> 16) | ($s9 * (1 << 5))),
     1956                0xff & ($s9 >> 3),
     1957                0xff & ($s9 >> 11),
     1958                0xff & (($s9 >> 19) | ($s10 * (1 << 2))),
     1959                0xff & ($s10 >> 6),
     1960                0xff & (($s10 >> 14) | ($s11 * (1 << 7))),
     1961                0xff & ($s11 >> 1),
     1962                0xff & ($s11 >> 9),
     1963                0xff & ($s11 >> 17)
     1964            )
     1965        );
     1966    }
     1967
     1968    /**
     1969     * @param string $s
     1970     * @return string
     1971     */
     1972    public static function sc_reduce($s)
     1973    {
     1974        $s0 = 2097151 & self::load_3(self::substr($s, 0, 3));
     1975        $s1 = 2097151 & (self::load_4(self::substr($s, 2, 4)) >> 5);
     1976        $s2 = 2097151 & (self::load_3(self::substr($s, 5, 3)) >> 2);
     1977        $s3 = 2097151 & (self::load_4(self::substr($s, 7, 4)) >> 7);
     1978        $s4 = 2097151 & (self::load_4(self::substr($s, 10, 4)) >> 4);
     1979        $s5 = 2097151 & (self::load_3(self::substr($s, 13, 3)) >> 1);
     1980        $s6 = 2097151 & (self::load_4(self::substr($s, 15, 4)) >> 6);
     1981        $s7 = 2097151 & (self::load_3(self::substr($s, 18, 4)) >> 3);
     1982        $s8 = 2097151 & self::load_3(self::substr($s, 21, 3));
     1983        $s9 = 2097151 & (self::load_4(self::substr($s, 23, 4)) >> 5);
     1984        $s10 = 2097151 & (self::load_3(self::substr($s, 26, 3)) >> 2);
     1985        $s11 = 2097151 & (self::load_4(self::substr($s, 28, 4)) >> 7);
     1986        $s12 = 2097151 & (self::load_4(self::substr($s, 31, 4)) >> 4);
     1987        $s13 = 2097151 & (self::load_3(self::substr($s, 34, 3)) >> 1);
     1988        $s14 = 2097151 & (self::load_4(self::substr($s, 36, 4)) >> 6);
     1989        $s15 = 2097151 & (self::load_3(self::substr($s, 39, 4)) >> 3);
     1990        $s16 = 2097151 & self::load_3(self::substr($s, 42, 3));
     1991        $s17 = 2097151 & (self::load_4(self::substr($s, 44, 4)) >> 5);
     1992        $s18 = 2097151 & (self::load_3(self::substr($s, 47, 3)) >> 2);
     1993        $s19 = 2097151 & (self::load_4(self::substr($s, 49, 4)) >> 7);
     1994        $s20 = 2097151 & (self::load_4(self::substr($s, 52, 4)) >> 4);
     1995        $s21 = 2097151 & (self::load_3(self::substr($s, 55, 3)) >> 1);
     1996        $s22 = 2097151 & (self::load_4(self::substr($s, 57, 4)) >> 6);
     1997        $s23 = (self::load_4(self::substr($s, 60, 4)) >> 3);
     1998
     1999        $s11 += $s23 * 666643;
     2000        $s12 += $s23 * 470296;
     2001        $s13 += $s23 * 654183;
     2002        $s14 -= $s23 * 997805;
     2003        $s15 += $s23 * 136657;
     2004        $s16 -= $s23 * 683901;
     2005
     2006        $s10 += $s22 * 666643;
     2007        $s11 += $s22 * 470296;
     2008        $s12 += $s22 * 654183;
     2009        $s13 -= $s22 * 997805;
     2010        $s14 += $s22 * 136657;
     2011        $s15 -= $s22 * 683901;
     2012
     2013        $s9 += $s21 * 666643;
     2014        $s10 += $s21 * 470296;
     2015        $s11 += $s21 * 654183;
     2016        $s12 -= $s21 * 997805;
     2017        $s13 += $s21 * 136657;
     2018        $s14 -= $s21 * 683901;
     2019
     2020        $s8 += $s20 * 666643;
     2021        $s9 += $s20 * 470296;
     2022        $s10 += $s20 * 654183;
     2023        $s11 -= $s20 * 997805;
     2024        $s12 += $s20 * 136657;
     2025        $s13 -= $s20 * 683901;
     2026
     2027        $s7 += $s19 * 666643;
     2028        $s8 += $s19 * 470296;
     2029        $s9 += $s19 * 654183;
     2030        $s10 -= $s19 * 997805;
     2031        $s11 += $s19 * 136657;
     2032        $s12 -= $s19 * 683901;
     2033
     2034        $s6 += $s18 * 666643;
     2035        $s7 += $s18 * 470296;
     2036        $s8 += $s18 * 654183;
     2037        $s9 -= $s18 * 997805;
     2038        $s10 += $s18 * 136657;
     2039        $s11 -= $s18 * 683901;
     2040
     2041        $carry6 = ($s6 + (1 << 20)) >> 21; $s7 += $carry6; $s6 -= $carry6 * (1 << 21);
     2042        $carry8 = ($s8 + (1 << 20)) >> 21; $s9 += $carry8; $s8 -= $carry8 * (1 << 21);
     2043        $carry10 = ($s10 + (1 << 20)) >> 21; $s11 += $carry10; $s10 -= $carry10 * (1 << 21);
     2044        $carry12 = ($s12 + (1 << 20)) >> 21; $s13 += $carry12; $s12 -= $carry12 * (1 << 21);
     2045        $carry14 = ($s14 + (1 << 20)) >> 21; $s15 += $carry14; $s14 -= $carry14 * (1 << 21);
     2046        $carry16 = ($s16 + (1 << 20)) >> 21; $s17 += $carry16; $s16 -= $carry16 * (1 << 21);
     2047
     2048        $carry7 = ($s7 + (1 << 20)) >> 21; $s8 += $carry7; $s7 -= $carry7 * (1 << 21);
     2049        $carry9 = ($s9 + (1 << 20)) >> 21; $s10 += $carry9; $s9 -= $carry9 * (1 << 21);
     2050        $carry11 = ($s11 + (1 << 20)) >> 21; $s12 += $carry11; $s11 -= $carry11 * (1 << 21);
     2051        $carry13 = ($s13 + (1 << 20)) >> 21; $s14 += $carry13; $s13 -= $carry13 * (1 << 21);
     2052        $carry15 = ($s15 + (1 << 20)) >> 21; $s16 += $carry15; $s15 -= $carry15 * (1 << 21);
     2053
     2054        $s5 += $s17 * 666643;
     2055        $s6 += $s17 * 470296;
     2056        $s7 += $s17 * 654183;
     2057        $s8 -= $s17 * 997805;
     2058        $s9 += $s17 * 136657;
     2059        $s10 -= $s17 * 683901;
     2060
     2061        $s4 += $s16 * 666643;
     2062        $s5 += $s16 * 470296;
     2063        $s6 += $s16 * 654183;
     2064        $s7 -= $s16 * 997805;
     2065        $s8 += $s16 * 136657;
     2066        $s9 -= $s16 * 683901;
     2067
     2068        $s3 += $s15 * 666643;
     2069        $s4 += $s15 * 470296;
     2070        $s5 += $s15 * 654183;
     2071        $s6 -= $s15 * 997805;
     2072        $s7 += $s15 * 136657;
     2073        $s8 -= $s15 * 683901;
     2074
     2075        $s2 += $s14 * 666643;
     2076        $s3 += $s14 * 470296;
     2077        $s4 += $s14 * 654183;
     2078        $s5 -= $s14 * 997805;
     2079        $s6 += $s14 * 136657;
     2080        $s7 -= $s14 * 683901;
     2081
     2082        $s1 += $s13 * 666643;
     2083        $s2 += $s13 * 470296;
     2084        $s3 += $s13 * 654183;
     2085        $s4 -= $s13 * 997805;
     2086        $s5 += $s13 * 136657;
     2087        $s6 -= $s13 * 683901;
     2088
     2089        $s0 += $s12 * 666643;
     2090        $s1 += $s12 * 470296;
     2091        $s2 += $s12 * 654183;
     2092        $s3 -= $s12 * 997805;
     2093        $s4 += $s12 * 136657;
     2094        $s5 -= $s12 * 683901;
     2095        $s12 = 0;
     2096
     2097        $carry0 = ($s0 + (1 << 20)) >> 21; $s1 += $carry0; $s0 -= $carry0 * (1 << 21);
     2098        $carry2 = ($s2 + (1 << 20)) >> 21; $s3 += $carry2; $s2 -= $carry2 * (1 << 21);
     2099        $carry4 = ($s4 + (1 << 20)) >> 21; $s5 += $carry4; $s4 -= $carry4 * (1 << 21);
     2100        $carry6 = ($s6 + (1 << 20)) >> 21; $s7 += $carry6; $s6 -= $carry6 * (1 << 21);
     2101        $carry8 = ($s8 + (1 << 20)) >> 21; $s9 += $carry8; $s8 -= $carry8 * (1 << 21);
     2102        $carry10 = ($s10 + (1 << 20)) >> 21; $s11 += $carry10; $s10 -= $carry10 * (1 << 21);
     2103
     2104        $carry1 = ($s1 + (1 << 20)) >> 21; $s2 += $carry1; $s1 -= $carry1 * (1 << 21);
     2105        $carry3 = ($s3 + (1 << 20)) >> 21; $s4 += $carry3; $s3 -= $carry3 * (1 << 21);
     2106        $carry5 = ($s5 + (1 << 20)) >> 21; $s6 += $carry5; $s5 -= $carry5 * (1 << 21);
     2107        $carry7 = ($s7 + (1 << 20)) >> 21; $s8 += $carry7; $s7 -= $carry7 * (1 << 21);
     2108        $carry9 = ($s9 + (1 << 20)) >> 21; $s10 += $carry9; $s9 -= $carry9 * (1 << 21);
     2109        $carry11 = ($s11 + (1 << 20)) >> 21; $s12 += $carry11; $s11 -= $carry11 * (1 << 21);
     2110
     2111        $s0 += $s12 * 666643;
     2112        $s1 += $s12 * 470296;
     2113        $s2 += $s12 * 654183;
     2114        $s3 -= $s12 * 997805;
     2115        $s4 += $s12 * 136657;
     2116        $s5 -= $s12 * 683901;
     2117        $s12 = 0;
     2118
     2119        $carry0 = $s0 >> 21; $s1 += $carry0; $s0 -= $carry0 * (1 << 21);
     2120        $carry1 = $s1 >> 21; $s2 += $carry1; $s1 -= $carry1 * (1 << 21);
     2121        $carry2 = $s2 >> 21; $s3 += $carry2; $s2 -= $carry2 * (1 << 21);
     2122        $carry3 = $s3 >> 21; $s4 += $carry3; $s3 -= $carry3 * (1 << 21);
     2123        $carry4 = $s4 >> 21; $s5 += $carry4; $s4 -= $carry4 * (1 << 21);
     2124        $carry5 = $s5 >> 21; $s6 += $carry5; $s5 -= $carry5 * (1 << 21);
     2125        $carry6 = $s6 >> 21; $s7 += $carry6; $s6 -= $carry6 * (1 << 21);
     2126        $carry7 = $s7 >> 21; $s8 += $carry7; $s7 -= $carry7 * (1 << 21);
     2127        $carry8 = $s8 >> 21; $s9 += $carry8; $s8 -= $carry8 * (1 << 21);
     2128        $carry9 = $s9 >> 21; $s10 += $carry9; $s9 -= $carry9 * (1 << 21);
     2129        $carry10 = $s10 >> 21; $s11 += $carry10; $s10 -= $carry10 * (1 << 21);
     2130        $carry11 = $s11 >> 21; $s12 += $carry11; $s11 -= $carry11 * (1 << 21);
     2131
     2132        $s0 += $s12 * 666643;
     2133        $s1 += $s12 * 470296;
     2134        $s2 += $s12 * 654183;
     2135        $s3 -= $s12 * 997805;
     2136        $s4 += $s12 * 136657;
     2137        $s5 -= $s12 * 683901;
     2138
     2139        $carry0 = $s0 >> 21; $s1 += $carry0; $s0 -= $carry0 * (1 << 21);
     2140        $carry1 = $s1 >> 21; $s2 += $carry1; $s1 -= $carry1 * (1 << 21);
     2141        $carry2 = $s2 >> 21; $s3 += $carry2; $s2 -= $carry2 * (1 << 21);
     2142        $carry3 = $s3 >> 21; $s4 += $carry3; $s3 -= $carry3 * (1 << 21);
     2143        $carry4 = $s4 >> 21; $s5 += $carry4; $s4 -= $carry4 * (1 << 21);
     2144        $carry5 = $s5 >> 21; $s6 += $carry5; $s5 -= $carry5 * (1 << 21);
     2145        $carry6 = $s6 >> 21; $s7 += $carry6; $s6 -= $carry6 * (1 << 21);
     2146        $carry7 = $s7 >> 21; $s8 += $carry7; $s7 -= $carry7 * (1 << 21);
     2147        $carry8 = $s8 >> 21; $s9 += $carry8; $s8 -= $carry8 * (1 << 21);
     2148        $carry9 = $s9 >> 21; $s10 += $carry9; $s9 -= $carry9 * (1 << 21);
     2149        $carry10 = $s10 >> 21; $s11 += $carry10; $s10 -= $carry10 * (1 << 21);
     2150
     2151        return self::intArrayToString(
     2152            array(
     2153                $s0 >> 0,
     2154                $s0 >> 8,
     2155                ($s0 >> 16) | ($s1 * (1 << 5)),
     2156                $s1 >> 3,
     2157                $s1 >> 11,
     2158                ($s1 >> 19) | ($s2 * (1 << 2)),
     2159                $s2 >> 6,
     2160                ($s2 >> 14) | ($s3 * (1 << 7)),
     2161                $s3 >> 1,
     2162                $s3 >> 9,
     2163                ($s3 >> 17) | ($s4 * (1 << 4)),
     2164                $s4 >> 4,
     2165                $s4 >> 12,
     2166                ($s4 >> 20) | ($s5 * (1 << 1)),
     2167                $s5 >> 7,
     2168                ($s5 >> 15) | ($s6 * (1 << 6)),
     2169                $s6 >> 2,
     2170                $s6 >> 10,
     2171                ($s6 >> 18) | ($s7 * (1 << 3)),
     2172                $s7 >> 5,
     2173                $s7 >> 13,
     2174                $s8 >> 0,
     2175                $s8 >> 8,
     2176                ($s8 >> 16) | ($s9 * (1 << 5)),
     2177                $s9 >> 3,
     2178                $s9 >> 11,
     2179                ($s9 >> 19) | ($s10 * (1 << 2)),
     2180                $s10 >> 6,
     2181                ($s10 >> 14) | ($s11 * (1 << 7)),
     2182                $s11 >> 1,
     2183                $s11 >> 9,
     2184                $s11 >> 17
     2185            )
     2186        );
     2187    }
     2188}
  • wp-includes/sodium_compat/src/Core/Curve25519/README.md

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
     1# Curve25519 Data Structures
     2
     3These are PHP implementation of the [structs used in the ref10 curve25519 code](https://github.com/jedisct1/libsodium/blob/master/src/libsodium/include/sodium/private/curve25519_ref10.h).
  • wp-includes/sodium_compat/src/Core/X25519.php

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
     1<?php
     2
     3/**
     4 * Class ParagonIE_Sodium_Core_X25519
     5 */
     6abstract class ParagonIE_Sodium_Core_X25519 extends ParagonIE_Sodium_Core_Curve25519
     7{
     8    /**
     9     * Alters the objects passed to this method in place.
     10     *
     11     * @param ParagonIE_Sodium_Core_Curve25519_Fe $f
     12     * @param ParagonIE_Sodium_Core_Curve25519_Fe $g
     13     * @param int $b
     14     */
     15    public static function fe_cswap(
     16        ParagonIE_Sodium_Core_Curve25519_Fe $f,
     17        ParagonIE_Sodium_Core_Curve25519_Fe $g,
     18        $b = 0
     19    ) {
     20        $f0 = (int) $f[0];
     21        $f1 = (int) $f[1];
     22        $f2 = (int) $f[2];
     23        $f3 = (int) $f[3];
     24        $f4 = (int) $f[4];
     25        $f5 = (int) $f[5];
     26        $f6 = (int) $f[6];
     27        $f7 = (int) $f[7];
     28        $f8 = (int) $f[8];
     29        $f9 = (int) $f[9];
     30        $g0 = (int) $g[0];
     31        $g1 = (int) $g[1];
     32        $g2 = (int) $g[2];
     33        $g3 = (int) $g[3];
     34        $g4 = (int) $g[4];
     35        $g5 = (int) $g[5];
     36        $g6 = (int) $g[6];
     37        $g7 = (int) $g[7];
     38        $g8 = (int) $g[8];
     39        $g9 = (int) $g[9];
     40        $b = -$b;
     41        $x0 = ($f0 ^ $g0) & $b;
     42        $x1 = ($f1 ^ $g1) & $b;
     43        $x2 = ($f2 ^ $g2) & $b;
     44        $x3 = ($f3 ^ $g3) & $b;
     45        $x4 = ($f4 ^ $g4) & $b;
     46        $x5 = ($f5 ^ $g5) & $b;
     47        $x6 = ($f6 ^ $g6) & $b;
     48        $x7 = ($f7 ^ $g7) & $b;
     49        $x8 = ($f8 ^ $g8) & $b;
     50        $x9 = ($f9 ^ $g9) & $b;
     51        $f[0] = $f0 ^ $x0;
     52        $f[1] = $f1 ^ $x1;
     53        $f[2] = $f2 ^ $x2;
     54        $f[3] = $f3 ^ $x3;
     55        $f[4] = $f4 ^ $x4;
     56        $f[5] = $f5 ^ $x5;
     57        $f[6] = $f6 ^ $x6;
     58        $f[7] = $f7 ^ $x7;
     59        $f[8] = $f8 ^ $x8;
     60        $f[9] = $f9 ^ $x9;
     61        $g[0] = $g0 ^ $x0;
     62        $g[1] = $g1 ^ $x1;
     63        $g[2] = $g2 ^ $x2;
     64        $g[3] = $g3 ^ $x3;
     65        $g[4] = $g4 ^ $x4;
     66        $g[5] = $g5 ^ $x5;
     67        $g[6] = $g6 ^ $x6;
     68        $g[7] = $g7 ^ $x7;
     69        $g[8] = $g8 ^ $x8;
     70        $g[9] = $g9 ^ $x9;
     71    }
     72
     73    /**
     74     * @param ParagonIE_Sodium_Core_Curve25519_Fe $f
     75     * @return ParagonIE_Sodium_Core_Curve25519_Fe
     76     */
     77    public static function fe_mul121666(ParagonIE_Sodium_Core_Curve25519_Fe $f)
     78    {
     79        $h = array(
     80            $f[0] * 121666,
     81            $f[1] * 121666,
     82            $f[2] * 121666,
     83            $f[3] * 121666,
     84            $f[4] * 121666,
     85            $f[5] * 121666,
     86            $f[6] * 121666,
     87            $f[7] * 121666,
     88            $f[8] * 121666,
     89            $f[9] * 121666
     90        );
     91
     92        $carry9 = ($h[9] + (1 << 24)) >> 25; $h[0] += $carry9 * 19; $h[9] -= $carry9 << 25;
     93        $carry1 = ($h[1] + (1 << 24)) >> 25; $h[2] += $carry1; $h[1] -= $carry1 << 25;
     94        $carry3 = ($h[3] + (1 << 24)) >> 25; $h[4] += $carry3; $h[3] -= $carry3 << 25;
     95        $carry5 = ($h[5] + (1 << 24)) >> 25; $h[6] += $carry5; $h[5] -= $carry5 << 25;
     96        $carry7 = ($h[7] + (1 << 24)) >> 25; $h[8] += $carry7; $h[7] -= $carry7 << 25;
     97
     98        $carry0 = ($h[0] + (1 << 25)) >> 26; $h[1] += $carry0; $h[0] -= $carry0 << 26;
     99        $carry2 = ($h[2] + (1 << 25)) >> 26; $h[3] += $carry2; $h[2] -= $carry2 << 26;
     100        $carry4 = ($h[4] + (1 << 25)) >> 26; $h[5] += $carry4; $h[4] -= $carry4 << 26;
     101        $carry6 = ($h[6] + (1 << 25)) >> 26; $h[7] += $carry6; $h[6] -= $carry6 << 26;
     102        $carry8 = ($h[8] + (1 << 25)) >> 26; $h[9] += $carry8; $h[8] -= $carry8 << 26;
     103
     104        foreach ($h as $i => $value) {
     105            $h[$i] = (int) $value;
     106        }
     107        return ParagonIE_Sodium_Core_Curve25519_Fe::fromArray($h);
     108    }
     109
     110    /**
     111     * @param string $n
     112     * @param string $p
     113     * @return string
     114     */
     115    public static function crypto_scalarmult_curve25519_ref10($n, $p)
     116    {
     117        # for (i = 0;i < 32;++i) e[i] = n[i];
     118        $e = '' . $n;
     119        # e[0] &= 248;
     120        $e[0] = self::intToChr(
     121            self::chrToInt($e[0]) & 248
     122        );
     123        # e[31] &= 127;
     124        # e[31] |= 64;
     125        $e[31] = self::intToChr(
     126            (self::chrToInt($e[31]) & 127) | 64
     127        );
     128        # fe_frombytes(x1,p);
     129        $x1 = self::fe_frombytes($p);
     130        # fe_1(x2);
     131        $x2 = self::fe_1();
     132        # fe_0(z2);
     133        $z2 = self::fe_0();
     134        # fe_copy(x3,x1);
     135        $x3 = self::fe_copy($x1);
     136        # fe_1(z3);
     137        $z3 = self::fe_1();
     138
     139        # swap = 0;
     140        $swap = 0;
     141
     142        # for (pos = 254;pos >= 0;--pos) {
     143        for ($pos = 254; $pos >= 0; --$pos) {
     144            # b = e[pos / 8] >> (pos & 7);
     145            $b = self::chrToInt(
     146                    $e[(int) floor($pos / 8)]
     147                ) >> ($pos & 7);
     148            # b &= 1;
     149            $b &= 1;
     150            # swap ^= b;
     151            $swap ^= $b;
     152            # fe_cswap(x2,x3,swap);
     153            self::fe_cswap($x2, $x3, $swap);
     154            # fe_cswap(z2,z3,swap);
     155            self::fe_cswap($z2, $z3, $swap);
     156            # swap = b;
     157            $swap = $b;
     158            # fe_sub(tmp0,x3,z3);
     159            $tmp0 = self::fe_sub($x3, $z3);
     160            # fe_sub(tmp1,x2,z2);
     161            $tmp1 = self::fe_sub($x2, $z2);
     162
     163            # fe_add(x2,x2,z2);
     164            $x2 = self::fe_add($x2, $z2);
     165
     166            # fe_add(z2,x3,z3);
     167            $z2 = self::fe_add($x3, $z3);
     168
     169            # fe_mul(z3,tmp0,x2);
     170            $z3 = self::fe_mul($tmp0, $x2);
     171
     172            # fe_mul(z2,z2,tmp1);
     173            $z2 = self::fe_mul($z2, $tmp1);
     174
     175            # fe_sq(tmp0,tmp1);
     176            $tmp0 = self::fe_sq($tmp1);
     177
     178            # fe_sq(tmp1,x2);
     179            $tmp1 = self::fe_sq($x2);
     180
     181            # fe_add(x3,z3,z2);
     182            $x3 = self::fe_add($z3, $z2);
     183
     184            # fe_sub(z2,z3,z2);
     185            $z2 = self::fe_sub($z3, $z2);
     186
     187            # fe_mul(x2,tmp1,tmp0);
     188            $x2 = self::fe_mul($tmp1, $tmp0);
     189
     190            # fe_sub(tmp1,tmp1,tmp0);
     191            $tmp1 = self::fe_sub($tmp1, $tmp0);
     192
     193            # fe_sq(z2,z2);
     194            $z2 = self::fe_sq($z2);
     195
     196            # fe_mul121666(z3,tmp1);
     197            $z3 = self::fe_mul121666($tmp1);
     198
     199            # fe_sq(x3,x3);
     200            $x3 = self::fe_sq($x3);
     201
     202            # fe_add(tmp0,tmp0,z3);
     203            $tmp0 = self::fe_add($tmp0, $z3);
     204
     205            # fe_mul(z3,x1,z2);
     206            $z3 = self::fe_mul($x1, $z2);
     207
     208            # fe_mul(z2,tmp1,tmp0);
     209            $z2 = self::fe_mul($tmp1, $tmp0);
     210        }
     211
     212        # fe_cswap(x2,x3,swap);
     213        self::fe_cswap($x2, $x3, $swap);
     214
     215        # fe_cswap(z2,z3,swap);
     216        self::fe_cswap($z2, $z3, $swap);
     217
     218        # fe_invert(z2,z2);
     219        $z2 = self::fe_invert($z2);
     220
     221        # fe_mul(x2,x2,z2);
     222        $x2 = self::fe_mul($x2, $z2);
     223        # fe_tobytes(q,x2);
     224        return self::fe_tobytes($x2);
     225    }
     226
     227    /**
     228     * @param ParagonIE_Sodium_Core_Curve25519_Fe $edwardsY
     229     * @param ParagonIE_Sodium_Core_Curve25519_Fe $edwardsZ
     230     * @return ParagonIE_Sodium_Core_Curve25519_Fe
     231     */
     232    public static function edwards_to_montgomery(
     233        ParagonIE_Sodium_Core_Curve25519_Fe $edwardsY,
     234        ParagonIE_Sodium_Core_Curve25519_Fe $edwardsZ
     235    ) {
     236        $tempX = self::fe_add($edwardsZ, $edwardsY);
     237        $tempZ = self::fe_sub($edwardsZ, $edwardsY);
     238        $tempZ = self::fe_invert($tempZ);
     239        return self::fe_mul($tempX, $tempZ);
     240    }
     241
     242    /**
     243     * @param string $n
     244     * @return string
     245     */
     246    public static function crypto_scalarmult_curve25519_ref10_base($n)
     247    {
     248        # for (i = 0;i < 32;++i) e[i] = n[i];
     249        $e = '' . $n;
     250        # e[0] &= 248;
     251        $e[0] = self::intToChr(
     252            self::chrToInt($e[0]) & 248
     253        );
     254        # e[31] &= 127;
     255        # e[31] |= 64;
     256        $e[31] = self::intToChr(
     257            (self::chrToInt($e[31]) & 127) | 64
     258        );
     259
     260        $A = self::ge_scalarmult_base($e);
     261        $pk = self::edwards_to_montgomery($A->Y, $A->Z);
     262        return self::fe_tobytes($pk);
     263    }
     264}
  • wp-includes/sodium_compat/phpunit.xml.dist

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
     1<?xml version="1.0" encoding="UTF-8"?>
     2<phpunit
     3    backupGlobals="true"
     4    backupStaticAttributes="false"
     5    bootstrap="vendor/autoload.php"
     6    colors="true"
     7    convertErrorsToExceptions="true"
     8    convertNoticesToExceptions="true"
     9    convertWarningsToExceptions="true"
     10    processIsolation="false"
     11    stopOnError="false"
     12    stopOnFailure="false"
     13    syntaxCheck="true"
     14>
     15    <testsuites>
     16        <testsuite name="Unit Tests">
     17            <directory suffix="Test.php">./tests/unit</directory>
     18        </testsuite>
     19    </testsuites>
     20    <testsuites>
     21        <testsuite name="Libsodium Compatibility Tests">
     22            <directory suffix="Test.php">./tests/compat</directory>
     23        </testsuite>
     24    </testsuites>
     25    <filter>
     26        <whitelist processUncoveredFilesFromWhitelist="true">
     27            <directory suffix=".php">./src</directory>
     28        </whitelist>
     29    </filter>
     30</phpunit>
     31 No newline at end of file
  • wp-includes/sodium_compat/tests/unit/CryptoTest.php

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
     1<?php
     2
     3class CryptoTest extends PHPUnit_Framework_TestCase
     4{
     5    public function setUp()
     6    {
     7        ParagonIE_Sodium_Compat::$disableFallbackForUnitTests = true;
     8    }
     9
     10    /**
     11     * @covers ParagonIE_Sodium_Compat::crypto_box()
     12     * @covers ParagonIE_Sodium_Compat::crypto_box_open()
     13     */
     14    public function testCryptoBox()
     15    {
     16        $nonce = str_repeat("\x00", 24);
     17        $message = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
     18        $message .= str_repeat("\x20", 64);
     19
     20        $alice_secret = ParagonIE_Sodium_Core_Util::hex2bin('69f208412d8dd5db9d0c6d18512e86f0ec75665ab841372d57b042b27ef89d8c');
     21        $alice_public = ParagonIE_Sodium_Core_Util::hex2bin('ac3a70ba35df3c3fae427a7c72021d68f2c1e044040b75f17313c0c8b5d4241d');
     22        $bob_secret = ParagonIE_Sodium_Core_Util::hex2bin('b581fb5ae182a16f603f39270d4e3b95bc008310b727a11dd4e784a0044d461b');
     23        $bob_public = ParagonIE_Sodium_Core_Util::hex2bin('e8980c86e032f1eb2975052e8d65bddd15c3b59641174ec9678a53789d92c754');
     24
     25        $alice_to_bob = ParagonIE_Sodium_Crypto::box_keypair_from_secretkey_and_publickey(
     26            $alice_secret,
     27            $bob_public
     28        );
     29        $bob_to_alice = ParagonIE_Sodium_Crypto::box_keypair_from_secretkey_and_publickey(
     30            $bob_secret,
     31            $alice_public
     32        );
     33
     34        $this->assertSame(
     35            bin2hex(ParagonIE_Sodium_Crypto::box($message, $nonce, $bob_to_alice)),
     36            bin2hex(ParagonIE_Sodium_Crypto::box($message, $nonce, $alice_to_bob)),
     37            'box'
     38        );
     39    }
     40
     41
     42    /**
     43     * @covers ParagonIE_Sodium_Compat::crypto_box_seal()
     44     * @covers ParagonIE_Sodium_Compat::crypto_box_seal_open()
     45     */
     46    public function testBoxSeal()
     47    {
     48        $message = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
     49
     50        $alice_box_kp = ParagonIE_Sodium_Core_Util::hex2bin(
     51            '15b36cb00213373fb3fb03958fb0cc0012ecaca112fd249d3cf0961e311caac9' .
     52            'fb4cb34f74a928b79123333c1e63d991060244cda98affee14c3398c6d315574'
     53        );
     54        $alice_box_publickey = ParagonIE_Sodium_Core_Util::hex2bin(
     55            'fb4cb34f74a928b79123333c1e63d991060244cda98affee14c3398c6d315574'
     56        );
     57
     58        $sealed_to_alice = ParagonIE_Sodium_Compat::crypto_box_seal($message, $alice_box_publickey);
     59
     60        $alice_opened = ParagonIE_Sodium_Compat::crypto_box_seal_open($sealed_to_alice, $alice_box_kp);
     61        $this->assertSame(
     62            $message,
     63            $alice_opened,
     64            'Decryption failed'
     65        );
     66    }
     67
     68    /**
     69     *
     70     */
     71    public function testKeypairs()
     72    {
     73        $box_keypair = ParagonIE_Sodium_Compat::crypto_box_keypair();
     74        $box_public = ParagonIE_Sodium_Compat::crypto_box_publickey($box_keypair);
     75
     76        $sealed = ParagonIE_Sodium_Compat::crypto_box_seal('Test message', $box_public);
     77        $opened = ParagonIE_Sodium_Compat::crypto_box_seal_open($sealed, $box_keypair);
     78        $this->assertSame(
     79            'Test message',
     80            $opened
     81        );
     82        #
     83
     84        $sign_keypair = ParagonIE_Sodium_Core_Util::hex2bin(
     85            'fcdf31aae72e280cc760186d83e41be216fe1f2c7407dd393ad3a45a2fa501a4' .
     86            'ee00f800ae9e986b994ec0af67fe6b017eb78704e81639eee7efa3d3a831d1bc' .
     87            'ee00f800ae9e986b994ec0af67fe6b017eb78704e81639eee7efa3d3a831d1bc'
     88        );
     89        $sign_secret = ParagonIE_Sodium_Compat::crypto_sign_secretkey($sign_keypair);
     90        $sign_public = ParagonIE_Sodium_Compat::crypto_sign_publickey($sign_keypair);
     91        $this->assertSame(
     92            ParagonIE_Sodium_Core_Util::substr($sign_secret, 32),
     93            $sign_public
     94        );
     95
     96        $sign_keypair = ParagonIE_Sodium_Compat::crypto_sign_keypair();
     97        $sign_secret = ParagonIE_Sodium_Compat::crypto_sign_secretkey($sign_keypair);
     98        $sign_public = ParagonIE_Sodium_Compat::crypto_sign_publickey($sign_keypair);
     99        $this->assertSame(
     100            ParagonIE_Sodium_Core_Util::substr($sign_secret, 32),
     101            $sign_public
     102        );
     103
     104        $sig = ParagonIE_Sodium_Compat::crypto_sign_detached('Test message', $sign_secret);
     105        $this->assertTrue(
     106            ParagonIE_Sodium_Compat::crypto_sign_verify_detached($sig, 'Test message', $sign_public)
     107        );
     108    }
     109
     110    /**
     111     * @covers ParagonIE_Sodium_Crypto::scalarmult_base()
     112     */
     113    public function testScalarmultBase()
     114    {
     115        $alice_secret = ParagonIE_Sodium_Core_Util::hex2bin('69f208412d8dd5db9d0c6d18512e86f0ec75665ab841372d57b042b27ef89d8c');
     116        $alice_public = ParagonIE_Sodium_Core_Util::hex2bin('ac3a70ba35df3c3fae427a7c72021d68f2c1e044040b75f17313c0c8b5d4241d');
     117
     118        $this->assertSame(
     119            bin2hex($alice_public),
     120            bin2hex(ParagonIE_Sodium_Crypto::scalarmult_base($alice_secret))
     121        );
     122    }
     123
     124    /**
     125     * @covers ParagonIE_Sodium_Crypto::scalarmult()
     126     */
     127    public function testScalarmult()
     128    {
     129        $alice_secret = ParagonIE_Sodium_Core_Util::hex2bin('69f208412d8dd5db9d0c6d18512e86f0ec75665ab841372d57b042b27ef89d8c');
     130        $alice_public = ParagonIE_Sodium_Core_Util::hex2bin('ac3a70ba35df3c3fae427a7c72021d68f2c1e044040b75f17313c0c8b5d4241d');
     131        $bob_secret = ParagonIE_Sodium_Core_Util::hex2bin('b581fb5ae182a16f603f39270d4e3b95bc008310b727a11dd4e784a0044d461b');
     132        $bob_public = ParagonIE_Sodium_Core_Util::hex2bin('e8980c86e032f1eb2975052e8d65bddd15c3b59641174ec9678a53789d92c754');
     133
     134        $this->assertSame(
     135            bin2hex(ParagonIE_Sodium_Crypto::scalarmult($alice_secret, $bob_public)),
     136            bin2hex(ParagonIE_Sodium_Crypto::scalarmult($bob_secret, $alice_public))
     137        );
     138    }
     139
     140    /**
     141     * @covers ParagonIE_Sodium_Crypto::sign_detached()
     142     */
     143    public function testSignDetached()
     144    {
     145        $secret = ParagonIE_Sodium_Core_Util::hex2bin(
     146            'fcdf31aae72e280cc760186d83e41be216fe1f2c7407dd393ad3a45a2fa501a4' .
     147            'ee00f800ae9e986b994ec0af67fe6b017eb78704e81639eee7efa3d3a831d1bc'
     148        );
     149        $message = 'Test message';
     150        $this->assertSame(
     151            '5e413e791d9bcdbaa1cfd4f83b01c73926f436a467cfc2634fc90651fb0465bfea76083b4ff247f925df96e89da3d9edc11029adf1601cd0f97d1b2c4b02e905',
     152            bin2hex(ParagonIE_Sodium_Crypto::sign_detached($message, $secret)),
     153            'Generated different signatures'
     154        );
     155
     156        $message = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.';
     157        $this->assertSame(
     158            '36a6d2748f6ab8f76c122a562d55343cb7c6f15c8a45bd55bd8b9e9fadd2363f370cb78fba42c550d487b9bd7413312b6490c8b3ee2cea638997172a9c8c250f',
     159            bin2hex(ParagonIE_Sodium_Crypto::sign_detached($message, $secret)),
     160            'Generated different signatures'
     161        );
     162
     163
     164    }
     165
     166    /**
     167     * @covers ParagonIE_Sodium_Crypto::sign()
     168     * @covers ParagonIE_Sodium_Crypto::sign_open()
     169     */
     170    public function testSign()
     171    {
     172        $secret = ParagonIE_Sodium_Core_Util::hex2bin(
     173            'fcdf31aae72e280cc760186d83e41be216fe1f2c7407dd393ad3a45a2fa501a4' .
     174            'ee00f800ae9e986b994ec0af67fe6b017eb78704e81639eee7efa3d3a831d1bc'
     175        );
     176        $public = ParagonIE_Sodium_Core_Util::hex2bin(
     177            'ee00f800ae9e986b994ec0af67fe6b017eb78704e81639eee7efa3d3a831d1bc'
     178        );
     179        $message = random_bytes(random_int(1, 1024));
     180        $signed = ParagonIE_Sodium_Compat::crypto_sign($message, $secret);
     181        $this->assertSame(
     182            bin2hex($message),
     183            bin2hex(ParagonIE_Sodium_Compat::crypto_sign_open($signed, $public)),
     184            'Signature broken with known good keys'
     185        );
     186        $sign_keypair = ParagonIE_Sodium_Compat::crypto_sign_keypair();
     187        $sign_secret = ParagonIE_Sodium_Compat::crypto_sign_secretkey($sign_keypair);
     188        $sign_public = ParagonIE_Sodium_Compat::crypto_sign_publickey($sign_keypair);
     189
     190        $message = random_bytes(random_int(1, 1024));
     191        $signed = ParagonIE_Sodium_Compat::crypto_sign($message, $sign_secret);
     192        $this->assertSame(
     193            bin2hex($message),
     194            bin2hex(ParagonIE_Sodium_Compat::crypto_sign_open($signed, $sign_public)),
     195            'Signature broken with random keys'
     196        );
     197    }
     198
     199    /**
     200     * @covers ParagonIE_Sodium_Compat::crypto_secretbox()
     201     * @covers ParagonIE_Sodium_Compat::crypto_secretbox_open()
     202     */
     203    public function testSecretbox()
     204    {
     205        $secret = random_bytes(32);
     206        $nonce = random_bytes(24);
     207
     208        $message = random_bytes(random_int(1, 1024));
     209        $cipher = ParagonIE_Sodium_Compat::crypto_secretbox($message, $nonce, $secret);
     210
     211        $this->assertSame(
     212            $message,
     213            ParagonIE_Sodium_Compat::crypto_secretbox_open($cipher, $nonce, $secret)
     214        );
     215    }
     216
     217    /**
     218     * @covers ParagonIE_Sodium_Crypto::sign_verify_detached()
     219     */
     220    public function testVerifyDetached()
     221    {
     222        $public = ParagonIE_Sodium_Core_Util::hex2bin('ee00f800ae9e986b994ec0af67fe6b017eb78704e81639eee7efa3d3a831d1bc');
     223
     224        $message = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.';
     225        $sig = ParagonIE_Sodium_Core_Util::hex2bin(
     226            '36a6d2748f6ab8f76c122a562d55343cb7c6f15c8a45bd55bd8b9e9fadd2363f' .
     227            '370cb78fba42c550d487b9bd7413312b6490c8b3ee2cea638997172a9c8c250f'
     228        );
     229        $this->assertTrue(
     230            ParagonIE_Sodium_Crypto::sign_verify_detached($sig, $message, $public),
     231            'Invalid signature verification checking'
     232        );
     233    }
     234}
  • wp-includes/sodium_compat/tests/unit/Blake2bTest.php

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
     1<?php
     2
     3class Blake2bTest extends PHPUnit_Framework_TestCase
     4{
     5    public function setUp()
     6    {
     7        ParagonIE_Sodium_Compat::$disableFallbackForUnitTests = true;
     8    }
     9
     10    /**
     11     * @covers ParagonIE_Sodium_Compat::crypto_generichash()
     12     */
     13    public function testGenericHash()
     14    {
     15        $this->assertSame(
     16            pack('H*', 'df654812bac492663825520ba2f6e67cf5ca5bdc13d4e7507a98cc4c2fcc3ad8'),
     17            ParagonIE_Sodium_Compat::crypto_generichash('Paragon Initiative Enterprises, LLC'),
     18            'Chosen input.'
     19        );
     20    }
     21
     22    /**
     23     * @covers ParagonIE_Sodium_Compat::crypto_generichash_init()
     24     * @covers ParagonIE_Sodium_Compat::crypto_generichash_update()
     25     * @covers ParagonIE_Sodium_Compat::crypto_generichash_final()
     26     */
     27    public function testGenericHashStream()
     28    {
     29        $ctx = ParagonIE_Sodium_Compat::crypto_generichash_init();
     30        ParagonIE_Sodium_Compat::crypto_generichash_update($ctx, 'Paragon Initiative ');
     31        ParagonIE_Sodium_Compat::crypto_generichash_update($ctx, 'Enterprises, LLC');
     32        $this->assertSame(
     33            'df654812bac492663825520ba2f6e67cf5ca5bdc13d4e7507a98cc4c2fcc3ad8',
     34            bin2hex(ParagonIE_Sodium_Compat::crypto_generichash_final($ctx)),
     35            'Chosen input.'
     36        );
     37    }
     38}
  • wp-includes/sodium_compat/src/Core/Curve25519/Ge/P3.php

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
     1<?php
     2
     3/**
     4 * Class ParagonIE_Sodium_Core_Curve25519_Ge_P3
     5 */
     6class ParagonIE_Sodium_Core_Curve25519_Ge_P3
     7{
     8    /**
     9     * @var ParagonIE_Sodium_Core_Curve25519_Fe
     10     */
     11    public $X;
     12
     13    /**
     14     * @var ParagonIE_Sodium_Core_Curve25519_Fe
     15     */
     16    public $Y;
     17
     18    /**
     19     * @var ParagonIE_Sodium_Core_Curve25519_Fe
     20     */
     21    public $Z;
     22
     23    /**
     24     * @var ParagonIE_Sodium_Core_Curve25519_Fe
     25     */
     26    public $T;
     27
     28    public function __construct(
     29        ParagonIE_Sodium_Core_Curve25519_Fe $x = null,
     30        ParagonIE_Sodium_Core_Curve25519_Fe $y = null,
     31        ParagonIE_Sodium_Core_Curve25519_Fe $z = null,
     32        ParagonIE_Sodium_Core_Curve25519_Fe $t = null
     33    ) {
     34        $this->X = $x;
     35        $this->Y = $y;
     36        $this->Z = $z;
     37        $this->T = $t;
     38    }
     39}
  • wp-admin/includes/file.php

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
    487487 *
    488488 * @param string $url the URL of the file to download
    489489 * @param int $timeout The timeout for the request to download the file default 300 seconds
     490 * @param string $public_key Ed25519 public key (for crypto_sign_verify_detached())
    490491 * @return mixed WP_Error on failure, string Filename on success.
    491492 */
    492 function download_url( $url, $timeout = 300 ) {
     493function download_url( $url, $timeout = 300, $public_key = null, $public_key_raw = false ) {
    493494        //WARNING: The file is not automatically deleted, The script must unlink() the file.
    494495        if ( ! $url )
    495496                return new WP_Error('http_no_url', __('Invalid URL Provided.'));
     
    520521                        return $md5_check;
    521522                }
    522523        }
     524        if ( $public_key ) {
     525        $content_ed25519_hex = wp_remote_retrieve_header( $response, 'content-ed25519' );
     526        $ed25519_check = verify_file_ed25519( $tmpfname, $public_key, $content_ed25519_hex );
     527            if ( is_wp_error( $ed25519_check ) ) {
     528                unlink( $tmpfname );
     529                return $ed25519_check;
     530        }
     531    }
    523532
    524533        return $tmpfname;
    525534}
    526535
     536/**
     537 * Verifies the Ed25519 signature of a file for a given public key.
     538 *
     539 * @since 4.8.0 (presumably)
     540 *
     541 * @param string $filename
     542 * @param string $public_key
     543 * @param string $signature
     544 * @return bool|object WP_Error on failure, true on success
     545 */
     546function verify_file_ed25519( $filename, $public_key, $signature ) {
     547    if ( ParagonIE_Sodium_Core_Util::strlen( $public_key ) === ParagonIE_Sodium_Compat::CRYPTO_SIGN_PUBLICKEYBYTES * 2 ) {
     548        $public_key = ParagonIE_Sodium_Compat::hex2bin($public_key);
     549    }
     550    if ( ParagonIE_Sodium_Core_Util::strlen( $signature ) === ParagonIE_Sodium_Compat::CRYPTO_SIGN_BYTES * 2 ) {
     551        $signature = ParagonIE_Sodium_Compat::hex2bin($signature);
     552    }
     553
     554    $file_contents = file_get_contents( $filename );
     555
     556    $verified = ParagonIE_Sodium_Compat::crypto_sign_verify_detached( $signature, $file_contents, $public_key );
     557    if ( $verified ) {
     558        return true;
     559    }
     560
     561    return new WP_Error( 'ed25519_mismatch', sprintf( __( 'The signature of the file (%1$s) is not valid for the given public key (%2$s).' ), bin2hex( $signature ), bin2hex( $public_key ) ) );
     562}
     563
    527564/**
    528565 * Calculates and compares the MD5 of a file to its expected value.
    529566 *
  • wp-includes/sodium_compat/src/Core/Salsa20.php

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
     1<?php
     2
     3/**
     4 * Class ParagonIE_Sodium_Core_Salsa20
     5 */
     6abstract class ParagonIE_Sodium_Core_Salsa20 extends ParagonIE_Sodium_Core_Util
     7{
     8    const ROUNDS = 20;
     9
     10    /**
     11     * Calculate an salsa20 hash of a single block
     12     *
     13     * @param string $in
     14     * @param string $k
     15     * @param string|null $c
     16     * @return string;
     17     */
     18    public static function core_salsa20($in, $k, $c = null)
     19    {
     20        if (self::strlen($k) < 32) {
     21            throw new RangeException('Key must be 32 bytes long');
     22        }
     23        if ($c === null) {
     24            $j0  = $x0  = 0x61707865;
     25            $j5  = $x5  = 0x3320646e;
     26            $j10 = $x10 = 0x79622d32;
     27            $j15 = $x15 = 0x6b206574;
     28        } else {
     29            $j0  = $x0  = self::load_4(self::substr($c,  0, 4));
     30            $j5  = $x5  = self::load_4(self::substr($c,  4, 4));
     31            $j10 = $x10 = self::load_4(self::substr($c,  8, 4));
     32            $j15 = $x15 = self::load_4(self::substr($c, 12, 4));
     33        }
     34        $j1  = $x1  = self::load_4(self::substr($k,  0, 4));
     35        $j2  = $x2  = self::load_4(self::substr($k,  4, 4));
     36        $j3  = $x3  = self::load_4(self::substr($k,  8, 4));
     37        $j4  = $x4  = self::load_4(self::substr($k, 12, 4));
     38        $j6  = $x6  = self::load_4(self::substr($in, 0, 4));
     39        $j7  = $x7  = self::load_4(self::substr($in, 4, 4));
     40        $j8  = $x8  = self::load_4(self::substr($in, 8, 4));
     41        $j9  = $x9  = self::load_4(self::substr($in, 12, 4));
     42        $j11 = $x11 = self::load_4(self::substr($k, 16, 4));
     43        $j12 = $x12 = self::load_4(self::substr($k, 20, 4));
     44        $j13 = $x13 = self::load_4(self::substr($k, 24, 4));
     45        $j14 = $x14 = self::load_4(self::substr($k, 28, 4));
     46
     47        for ($i = self::ROUNDS; $i > 0; $i -= 2) {
     48            $x4 ^= self::rotate($x0 + $x12, 7);
     49            $x8 ^= self::rotate($x4 + $x0, 9);
     50            $x12 ^= self::rotate($x8 + $x4, 13);
     51            $x0 ^= self::rotate($x12 + $x8, 18);
     52
     53            $x9 ^= self::rotate($x5 + $x1, 7);
     54            $x13 ^= self::rotate($x9 + $x5, 9);
     55            $x1 ^= self::rotate($x13 + $x9, 13);
     56            $x5 ^= self::rotate($x1 + $x13, 18);
     57
     58            $x14 ^= self::rotate($x10 + $x6, 7);
     59            $x2 ^= self::rotate($x14 + $x10, 9);
     60            $x6 ^= self::rotate($x2 + $x14, 13);
     61            $x10 ^= self::rotate($x6 + $x2, 18);
     62
     63            $x3 ^= self::rotate($x15 + $x11, 7);
     64            $x7 ^= self::rotate($x3 + $x15, 9);
     65            $x11 ^= self::rotate($x7 + $x3, 13);
     66            $x15 ^= self::rotate($x11 + $x7, 18);
     67
     68            $x1 ^= self::rotate($x0 + $x3, 7);
     69            $x2 ^= self::rotate($x1 + $x0, 9);
     70            $x3 ^= self::rotate($x2 + $x1, 13);
     71            $x0 ^= self::rotate($x3 + $x2, 18);
     72
     73            $x6 ^= self::rotate($x5 + $x4, 7);
     74            $x7 ^= self::rotate($x6 + $x5, 9);
     75            $x4 ^= self::rotate($x7 + $x6, 13);
     76            $x5 ^= self::rotate($x4 + $x7, 18);
     77
     78            $x11 ^= self::rotate($x10 + $x9, 7);
     79            $x8 ^= self::rotate($x11 + $x10, 9);
     80            $x9 ^= self::rotate($x8 + $x11, 13);
     81            $x10 ^= self::rotate($x9 + $x8, 18);
     82
     83            $x12 ^= self::rotate($x15 + $x14, 7);
     84            $x13 ^= self::rotate($x12 + $x15, 9);
     85            $x14 ^= self::rotate($x13 + $x12, 13);
     86            $x15 ^= self::rotate($x14 + $x13, 18);
     87        }
     88
     89        $x0  += $j0;
     90        $x1  += $j1;
     91        $x2  += $j2;
     92        $x3  += $j3;
     93        $x4  += $j4;
     94        $x5  += $j5;
     95        $x6  += $j6;
     96        $x7  += $j7;
     97        $x8  += $j8;
     98        $x9  += $j9;
     99        $x10 += $j10;
     100        $x11 += $j11;
     101        $x12 += $j12;
     102        $x13 += $j13;
     103        $x14 += $j14;
     104        $x15 += $j15;
     105
     106        return self::store32_le($x0) .
     107            self::store32_le($x1) .
     108            self::store32_le($x2) .
     109            self::store32_le($x3) .
     110            self::store32_le($x4) .
     111            self::store32_le($x5) .
     112            self::store32_le($x6) .
     113            self::store32_le($x7) .
     114            self::store32_le($x8) .
     115            self::store32_le($x9) .
     116            self::store32_le($x10) .
     117            self::store32_le($x11) .
     118            self::store32_le($x12) .
     119            self::store32_le($x13) .
     120            self::store32_le($x14) .
     121            self::store32_le($x15);
     122    }
     123
     124    /**
     125     * @param int $len
     126     * @param string $nonce
     127     * @param string $key
     128     * @return string
     129     */
     130    public static function salsa20($len, $nonce, $key)
     131    {
     132        if (self::strlen($key) !== 32) {
     133            throw new RangeException('Key must be 32 bytes long');
     134        }
     135        $kcopy = '' . $key;
     136        $in = self::substr($nonce, 0, 8) . str_repeat("\0", 8);
     137        $c = '';
     138        while ($len >= 64) {
     139            $c .= self::core_salsa20($in, $kcopy, null);
     140            $u = 1;
     141            // Internal counter.
     142            for ($i = 8; $i < 16; ++$i) {
     143                $u += self::chrToInt($in[$i]);
     144                $in[$i] = self::intToChr($u & 0xff);
     145                $u >>= 8;
     146            }
     147            $len -= 64;
     148        }
     149        if ($len > 0) {
     150            $c .= self::substr(
     151                self::core_salsa20($in, $kcopy, null),
     152                0,
     153                $len
     154            );
     155        }
     156        ParagonIE_Sodium_Compat::memzero($kcopy);
     157        return $c;
     158    }
     159
     160    /**
     161     * @param string $m
     162     * @param string $n
     163     * @param int $ic
     164     * @param string $k
     165     * @return string
     166     */
     167    public static function salsa20_xor_ic($m, $n, $ic, $k)
     168    {
     169        $mlen = self::strlen($m);
     170        if ($mlen < 1) {
     171            return '';
     172        }
     173        $kcopy = self::substr($k, 0, 32);
     174        $in = self::substr($n, 0, 8);
     175        // Initialize the counter
     176        for ($i = 8; $i < 16; ++$i) {
     177            $in .= self::intToChr($ic & 0xff);
     178            $ic >>= 8;
     179        }
     180
     181        $c = '';
     182        while ($mlen >= 64) {
     183            $block = self::core_salsa20($in, $kcopy, null);
     184            $c .= self::xorStrings(
     185                self::substr($m, 0, 64),
     186                self::substr($block, 0, 64)
     187            );
     188            $u = 1;
     189            for ($i = 8; $i < 16; ++$i) {
     190                $u += self::chrToInt($in[$i]);
     191                $in[$i] = self::intToChr($u & 0xff);
     192                $u >>= 8;
     193            }
     194
     195            $mlen -= 64;
     196            $m = self::substr($m, 64);
     197        }
     198
     199        if ($mlen) {
     200            $block = self::core_salsa20($in, $kcopy, null);
     201            $c .= self::xorStrings(
     202                self::substr($m, 0, $mlen),
     203                self::substr($block, 0, $mlen)
     204            );
     205        }
     206        ParagonIE_Sodium_Compat::memzero($block);
     207        ParagonIE_Sodium_Compat::memzero($kcopy);
     208
     209        return $c;
     210    }
     211
     212    /**
     213     * @param string $message
     214     * @param string $nonce
     215     * @param string $key
     216     * @return string
     217     */
     218    public static function salsa20_xor($message, $nonce, $key)
     219    {
     220        return self::xorStrings(
     221            $message,
     222            self::salsa20(
     223                self::strlen($message),
     224                $nonce,
     225                $key
     226            )
     227        );
     228    }
     229
     230    /**
     231     * @param int $u
     232     * @param int $c
     233     * @return int
     234     */
     235    public static function rotate($u, $c)
     236    {
     237        $u &= 0xffffffff;
     238        $c %= 32;
     239        return 0xffffffff & (($u << $c) | ($u >> (32 - $c)));
     240    }
     241}