wp/wp-includes/sodium_compat/src/Compat.php
changeset 18 be944660c56a
parent 16 a86126ab1dd4
child 19 3d72ae0968f4
equal deleted inserted replaced
17:34716fd837a4 18:be944660c56a
    42      *
    42      *
    43      * @var bool
    43      * @var bool
    44      */
    44      */
    45     public static $fastMult = false;
    45     public static $fastMult = false;
    46 
    46 
       
    47     const LIBRARY_MAJOR_VERSION = 9;
       
    48     const LIBRARY_MINOR_VERSION = 1;
    47     const LIBRARY_VERSION_MAJOR = 9;
    49     const LIBRARY_VERSION_MAJOR = 9;
    48     const LIBRARY_VERSION_MINOR = 1;
    50     const LIBRARY_VERSION_MINOR = 1;
    49     const VERSION_STRING = 'polyfill-1.0.8';
    51     const VERSION_STRING = 'polyfill-1.0.8';
    50 
    52 
    51     // From libsodium
    53     // From libsodium
    76     const CRYPTO_BOX_PUBLICKEYBYTES = 32;
    78     const CRYPTO_BOX_PUBLICKEYBYTES = 32;
    77     const CRYPTO_BOX_KEYPAIRBYTES = 64;
    79     const CRYPTO_BOX_KEYPAIRBYTES = 64;
    78     const CRYPTO_BOX_MACBYTES = 16;
    80     const CRYPTO_BOX_MACBYTES = 16;
    79     const CRYPTO_BOX_NONCEBYTES = 24;
    81     const CRYPTO_BOX_NONCEBYTES = 24;
    80     const CRYPTO_BOX_SEEDBYTES = 32;
    82     const CRYPTO_BOX_SEEDBYTES = 32;
       
    83     const CRYPTO_CORE_RISTRETTO255_BYTES = 32;
       
    84     const CRYPTO_CORE_RISTRETTO255_SCALARBYTES = 32;
       
    85     const CRYPTO_CORE_RISTRETTO255_HASHBYTES = 64;
       
    86     const CRYPTO_CORE_RISTRETTO255_NONREDUCEDSCALARBYTES = 64;
    81     const CRYPTO_KDF_BYTES_MIN = 16;
    87     const CRYPTO_KDF_BYTES_MIN = 16;
    82     const CRYPTO_KDF_BYTES_MAX = 64;
    88     const CRYPTO_KDF_BYTES_MAX = 64;
    83     const CRYPTO_KDF_CONTEXTBYTES = 8;
    89     const CRYPTO_KDF_CONTEXTBYTES = 8;
    84     const CRYPTO_KDF_KEYBYTES = 32;
    90     const CRYPTO_KDF_KEYBYTES = 32;
    85     const CRYPTO_KX_BYTES = 32;
    91     const CRYPTO_KX_BYTES = 32;
   111     const CRYPTO_PWHASH_SCRYPTSALSA208SHA256_MEMLIMIT_INTERACTIVE = 16777216;
   117     const CRYPTO_PWHASH_SCRYPTSALSA208SHA256_MEMLIMIT_INTERACTIVE = 16777216;
   112     const CRYPTO_PWHASH_SCRYPTSALSA208SHA256_OPSLIMIT_SENSITIVE = 33554432;
   118     const CRYPTO_PWHASH_SCRYPTSALSA208SHA256_OPSLIMIT_SENSITIVE = 33554432;
   113     const CRYPTO_PWHASH_SCRYPTSALSA208SHA256_MEMLIMIT_SENSITIVE = 1073741824;
   119     const CRYPTO_PWHASH_SCRYPTSALSA208SHA256_MEMLIMIT_SENSITIVE = 1073741824;
   114     const CRYPTO_SCALARMULT_BYTES = 32;
   120     const CRYPTO_SCALARMULT_BYTES = 32;
   115     const CRYPTO_SCALARMULT_SCALARBYTES = 32;
   121     const CRYPTO_SCALARMULT_SCALARBYTES = 32;
       
   122     const CRYPTO_SCALARMULT_RISTRETTO255_BYTES = 32;
       
   123     const CRYPTO_SCALARMULT_RISTRETTO255_SCALARBYTES = 32;
   116     const CRYPTO_SHORTHASH_BYTES = 8;
   124     const CRYPTO_SHORTHASH_BYTES = 8;
   117     const CRYPTO_SHORTHASH_KEYBYTES = 16;
   125     const CRYPTO_SHORTHASH_KEYBYTES = 16;
   118     const CRYPTO_SECRETBOX_KEYBYTES = 32;
   126     const CRYPTO_SECRETBOX_KEYBYTES = 32;
   119     const CRYPTO_SECRETBOX_MACBYTES = 16;
   127     const CRYPTO_SECRETBOX_MACBYTES = 16;
   120     const CRYPTO_SECRETBOX_NONCEBYTES = 24;
   128     const CRYPTO_SECRETBOX_NONCEBYTES = 24;
   131     const CRYPTO_SIGN_PUBLICKEYBYTES = 32;
   139     const CRYPTO_SIGN_PUBLICKEYBYTES = 32;
   132     const CRYPTO_SIGN_SECRETKEYBYTES = 64;
   140     const CRYPTO_SIGN_SECRETKEYBYTES = 64;
   133     const CRYPTO_SIGN_KEYPAIRBYTES = 96;
   141     const CRYPTO_SIGN_KEYPAIRBYTES = 96;
   134     const CRYPTO_STREAM_KEYBYTES = 32;
   142     const CRYPTO_STREAM_KEYBYTES = 32;
   135     const CRYPTO_STREAM_NONCEBYTES = 24;
   143     const CRYPTO_STREAM_NONCEBYTES = 24;
       
   144     const CRYPTO_STREAM_XCHACHA20_KEYBYTES = 32;
       
   145     const CRYPTO_STREAM_XCHACHA20_NONCEBYTES = 24;
   136 
   146 
   137     /**
   147     /**
   138      * Add two numbers (little-endian unsigned), storing the value in the first
   148      * Add two numbers (little-endian unsigned), storing the value in the first
   139      * parameter.
   149      * parameter.
   140      *
   150      *
   723         $nonce = '',
   733         $nonce = '',
   724         $key = ''
   734         $key = ''
   725     ) {
   735     ) {
   726         /* Type checks: */
   736         /* Type checks: */
   727         ParagonIE_Sodium_Core_Util::declareScalarType($plaintext, 'string', 1);
   737         ParagonIE_Sodium_Core_Util::declareScalarType($plaintext, 'string', 1);
   728         ParagonIE_Sodium_Core_Util::declareScalarType($assocData, 'string', 2);
   738         if (!is_null($assocData)) {
       
   739             ParagonIE_Sodium_Core_Util::declareScalarType($assocData, 'string', 2);
       
   740         }
   729         ParagonIE_Sodium_Core_Util::declareScalarType($nonce, 'string', 3);
   741         ParagonIE_Sodium_Core_Util::declareScalarType($nonce, 'string', 3);
   730         ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 4);
   742         ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 4);
   731 
   743 
   732         /* Input validation: */
   744         /* Input validation: */
   733         if (ParagonIE_Sodium_Core_Util::strlen($nonce) !== self::CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES) {
   745         if (ParagonIE_Sodium_Core_Util::strlen($nonce) !== self::CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES) {
   810         $key = '',
   822         $key = '',
   811         $dontFallback = false
   823         $dontFallback = false
   812     ) {
   824     ) {
   813         /* Type checks: */
   825         /* Type checks: */
   814         ParagonIE_Sodium_Core_Util::declareScalarType($ciphertext, 'string', 1);
   826         ParagonIE_Sodium_Core_Util::declareScalarType($ciphertext, 'string', 1);
   815         ParagonIE_Sodium_Core_Util::declareScalarType($assocData, 'string', 2);
   827         if (!is_null($assocData)) {
       
   828             ParagonIE_Sodium_Core_Util::declareScalarType($assocData, 'string', 2);
       
   829         } else {
       
   830             $assocData = '';
       
   831         }
   816         ParagonIE_Sodium_Core_Util::declareScalarType($nonce, 'string', 3);
   832         ParagonIE_Sodium_Core_Util::declareScalarType($nonce, 'string', 3);
   817         ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 4);
   833         ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 4);
   818 
   834 
   819         /* Input validation: */
   835         /* Input validation: */
   820         if (ParagonIE_Sodium_Core_Util::strlen($nonce) !== self::CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NPUBBYTES) {
   836         if (ParagonIE_Sodium_Core_Util::strlen($nonce) !== self::CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NPUBBYTES) {
   881         $key = '',
   897         $key = '',
   882         $dontFallback = false
   898         $dontFallback = false
   883     ) {
   899     ) {
   884         /* Type checks: */
   900         /* Type checks: */
   885         ParagonIE_Sodium_Core_Util::declareScalarType($plaintext, 'string', 1);
   901         ParagonIE_Sodium_Core_Util::declareScalarType($plaintext, 'string', 1);
   886         ParagonIE_Sodium_Core_Util::declareScalarType($assocData, 'string', 2);
   902         if (!is_null($assocData)) {
       
   903             ParagonIE_Sodium_Core_Util::declareScalarType($assocData, 'string', 2);
       
   904         } else {
       
   905             $assocData = '';
       
   906         }
   887         ParagonIE_Sodium_Core_Util::declareScalarType($nonce, 'string', 3);
   907         ParagonIE_Sodium_Core_Util::declareScalarType($nonce, 'string', 3);
   888         ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 4);
   908         ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 4);
   889 
   909 
   890         /* Input validation: */
   910         /* Input validation: */
   891         if (ParagonIE_Sodium_Core_Util::strlen($nonce) !== self::CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NPUBBYTES) {
   911         if (ParagonIE_Sodium_Core_Util::strlen($nonce) !== self::CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NPUBBYTES) {
  1684      *
  1704      *
  1685      * @param string $my_secret
  1705      * @param string $my_secret
  1686      * @param string $their_public
  1706      * @param string $their_public
  1687      * @param string $client_public
  1707      * @param string $client_public
  1688      * @param string $server_public
  1708      * @param string $server_public
  1689      * @return string
  1709      * @param bool $dontFallback
  1690      * @throws SodiumException
  1710      * @return string
  1691      * @throws TypeError
  1711      * @throws SodiumException
  1692      * @psalm-suppress MixedArgument
  1712      * @throws TypeError
  1693      */
  1713      * @psalm-suppress MixedArgument
  1694     public static function crypto_kx($my_secret, $their_public, $client_public, $server_public)
  1714      */
       
  1715     public static function crypto_kx($my_secret, $their_public, $client_public, $server_public, $dontFallback = false)
  1695     {
  1716     {
  1696         /* Type checks: */
  1717         /* Type checks: */
  1697         ParagonIE_Sodium_Core_Util::declareScalarType($my_secret, 'string', 1);
  1718         ParagonIE_Sodium_Core_Util::declareScalarType($my_secret, 'string', 1);
  1698         ParagonIE_Sodium_Core_Util::declareScalarType($their_public, 'string', 2);
  1719         ParagonIE_Sodium_Core_Util::declareScalarType($their_public, 'string', 2);
  1699         ParagonIE_Sodium_Core_Util::declareScalarType($client_public, 'string', 3);
  1720         ParagonIE_Sodium_Core_Util::declareScalarType($client_public, 'string', 3);
  1711         }
  1732         }
  1712         if (ParagonIE_Sodium_Core_Util::strlen($server_public) !== self::CRYPTO_BOX_PUBLICKEYBYTES) {
  1733         if (ParagonIE_Sodium_Core_Util::strlen($server_public) !== self::CRYPTO_BOX_PUBLICKEYBYTES) {
  1713             throw new SodiumException('Argument 4 must be CRYPTO_BOX_PUBLICKEYBYTES long.');
  1734             throw new SodiumException('Argument 4 must be CRYPTO_BOX_PUBLICKEYBYTES long.');
  1714         }
  1735         }
  1715 
  1736 
  1716         if (self::useNewSodiumAPI()) {
  1737         if (self::useNewSodiumAPI() && !$dontFallback) {
  1717             if (is_callable('sodium_crypto_kx')) {
  1738             if (is_callable('sodium_crypto_kx')) {
  1718                 return (string) sodium_crypto_kx(
  1739                 return (string) sodium_crypto_kx(
  1719                     $my_secret,
  1740                     $my_secret,
  1720                     $their_public,
  1741                     $their_public,
  1721                     $client_public,
  1742                     $client_public,
  3046     public static function crypto_stream_keygen()
  3067     public static function crypto_stream_keygen()
  3047     {
  3068     {
  3048         return random_bytes(self::CRYPTO_STREAM_KEYBYTES);
  3069         return random_bytes(self::CRYPTO_STREAM_KEYBYTES);
  3049     }
  3070     }
  3050 
  3071 
       
  3072 
       
  3073     /**
       
  3074      * Expand a key and nonce into a keystream of pseudorandom bytes.
       
  3075      *
       
  3076      * @param int $len Number of bytes desired
       
  3077      * @param string $nonce Number to be used Once; must be 24 bytes
       
  3078      * @param string $key XChaCha20 key
       
  3079      * @param bool $dontFallback
       
  3080      * @return string       Pseudorandom stream that can be XORed with messages
       
  3081      *                      to provide encryption (but not authentication; see
       
  3082      *                      Poly1305 or crypto_auth() for that, which is not
       
  3083      *                      optional for security)
       
  3084      * @throws SodiumException
       
  3085      * @throws TypeError
       
  3086      * @psalm-suppress MixedArgument
       
  3087      */
       
  3088     public static function crypto_stream_xchacha20($len, $nonce, $key, $dontFallback = false)
       
  3089     {
       
  3090         /* Type checks: */
       
  3091         ParagonIE_Sodium_Core_Util::declareScalarType($len, 'int', 1);
       
  3092         ParagonIE_Sodium_Core_Util::declareScalarType($nonce, 'string', 2);
       
  3093         ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 3);
       
  3094 
       
  3095         /* Input validation: */
       
  3096         if (ParagonIE_Sodium_Core_Util::strlen($nonce) !== self::CRYPTO_STREAM_XCHACHA20_NONCEBYTES) {
       
  3097             throw new SodiumException('Argument 2 must be CRYPTO_SECRETBOX_XCHACHA20_NONCEBYTES long.');
       
  3098         }
       
  3099         if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_STREAM_XCHACHA20_KEYBYTES) {
       
  3100             throw new SodiumException('Argument 3 must be CRYPTO_STREAM_XCHACHA20_KEYBYTES long.');
       
  3101         }
       
  3102 
       
  3103         if (self::useNewSodiumAPI() && !$dontFallback) {
       
  3104             return sodium_crypto_stream_xchacha20($len, $nonce, $key);
       
  3105         }
       
  3106         if (PHP_INT_SIZE === 4) {
       
  3107             return ParagonIE_Sodium_Core32_XChaCha20::stream($len, $nonce, $key);
       
  3108         }
       
  3109         return ParagonIE_Sodium_Core_XChaCha20::stream($len, $nonce, $key);
       
  3110     }
       
  3111 
       
  3112     /**
       
  3113      * DANGER! UNAUTHENTICATED ENCRYPTION!
       
  3114      *
       
  3115      * Unless you are following expert advice, do not used this feature.
       
  3116      *
       
  3117      * Algorithm: XChaCha20
       
  3118      *
       
  3119      * This DOES NOT provide ciphertext integrity.
       
  3120      *
       
  3121      * @param string $message Plaintext message
       
  3122      * @param string $nonce Number to be used Once; must be 24 bytes
       
  3123      * @param string $key Encryption key
       
  3124      * @return string         Encrypted text which is vulnerable to chosen-
       
  3125      *                        ciphertext attacks unless you implement some
       
  3126      *                        other mitigation to the ciphertext (i.e.
       
  3127      *                        Encrypt then MAC)
       
  3128      * @param bool $dontFallback
       
  3129      * @throws SodiumException
       
  3130      * @throws TypeError
       
  3131      * @psalm-suppress MixedArgument
       
  3132      */
       
  3133     public static function crypto_stream_xchacha20_xor($message, $nonce, $key, $dontFallback = false)
       
  3134     {
       
  3135         /* Type checks: */
       
  3136         ParagonIE_Sodium_Core_Util::declareScalarType($message, 'string', 1);
       
  3137         ParagonIE_Sodium_Core_Util::declareScalarType($nonce, 'string', 2);
       
  3138         ParagonIE_Sodium_Core_Util::declareScalarType($key, 'string', 3);
       
  3139 
       
  3140         /* Input validation: */
       
  3141         if (ParagonIE_Sodium_Core_Util::strlen($nonce) !== self::CRYPTO_STREAM_XCHACHA20_NONCEBYTES) {
       
  3142             throw new SodiumException('Argument 2 must be CRYPTO_SECRETBOX_XCHACHA20_NONCEBYTES long.');
       
  3143         }
       
  3144         if (ParagonIE_Sodium_Core_Util::strlen($key) !== self::CRYPTO_STREAM_XCHACHA20_KEYBYTES) {
       
  3145             throw new SodiumException('Argument 3 must be CRYPTO_SECRETBOX_XCHACHA20_KEYBYTES long.');
       
  3146         }
       
  3147 
       
  3148         if (self::useNewSodiumAPI() && !$dontFallback) {
       
  3149             return sodium_crypto_stream_xchacha20_xor($message, $nonce, $key);
       
  3150         }
       
  3151         if (PHP_INT_SIZE === 4) {
       
  3152             return ParagonIE_Sodium_Core32_XChaCha20::streamXorIc($message, $nonce, $key);
       
  3153         }
       
  3154         return ParagonIE_Sodium_Core_XChaCha20::streamXorIc($message, $nonce, $key);
       
  3155     }
       
  3156 
       
  3157     /**
       
  3158      * Return a secure random key for use with crypto_stream_xchacha20
       
  3159      *
       
  3160      * @return string
       
  3161      * @throws Exception
       
  3162      * @throws Error
       
  3163      */
       
  3164     public static function crypto_stream_xchacha20_keygen()
       
  3165     {
       
  3166         return random_bytes(self::CRYPTO_STREAM_XCHACHA20_KEYBYTES);
       
  3167     }
       
  3168 
  3051     /**
  3169     /**
  3052      * Cache-timing-safe implementation of hex2bin().
  3170      * Cache-timing-safe implementation of hex2bin().
  3053      *
  3171      *
  3054      * @param string $string Hexadecimal string
  3172      * @param string $string Hexadecimal string
  3055      * @return string        Raw binary string
  3173      * @return string        Raw binary string
  3111         }
  3229         }
  3112         $var = $copy;
  3230         $var = $copy;
  3113     }
  3231     }
  3114 
  3232 
  3115     /**
  3233     /**
       
  3234      * @param string $str
       
  3235      * @return bool
       
  3236      *
       
  3237      * @throws SodiumException
       
  3238      */
       
  3239     public static function is_zero($str)
       
  3240     {
       
  3241         $d = 0;
       
  3242         for ($i = 0; $i < 32; ++$i) {
       
  3243             $d |= ParagonIE_Sodium_Core_Util::chrToInt($str[$i]);
       
  3244         }
       
  3245         return ((($d - 1) >> 31) & 1) === 1;
       
  3246     }
       
  3247 
       
  3248     /**
  3116      * The equivalent to the libsodium minor version we aim to be compatible
  3249      * The equivalent to the libsodium minor version we aim to be compatible
  3117      * with (sans pwhash and memzero).
  3250      * with (sans pwhash and memzero).
  3118      *
  3251      *
  3119      * @return int
  3252      * @return int
  3120      * @psalm-suppress MixedInferredReturnType
       
  3121      * @psalm-suppress UndefinedFunction
       
  3122      */
  3253      */
  3123     public static function library_version_major()
  3254     public static function library_version_major()
  3124     {
  3255     {
  3125         if (self::useNewSodiumAPI()) {
  3256         if (self::useNewSodiumAPI() && defined('SODIUM_LIBRARY_MAJOR_VERSION')) {
  3126             return sodium_library_version_major();
  3257             return SODIUM_LIBRARY_MAJOR_VERSION;
  3127         }
  3258         }
  3128         if (self::use_fallback('library_version_major')) {
  3259         if (self::use_fallback('library_version_major')) {
       
  3260             /** @psalm-suppress UndefinedFunction */
  3129             return (int) call_user_func('\\Sodium\\library_version_major');
  3261             return (int) call_user_func('\\Sodium\\library_version_major');
  3130         }
  3262         }
  3131         return self::LIBRARY_VERSION_MAJOR;
  3263         return self::LIBRARY_VERSION_MAJOR;
  3132     }
  3264     }
  3133 
  3265 
  3134     /**
  3266     /**
  3135      * The equivalent to the libsodium minor version we aim to be compatible
  3267      * The equivalent to the libsodium minor version we aim to be compatible
  3136      * with (sans pwhash and memzero).
  3268      * with (sans pwhash and memzero).
  3137      *
  3269      *
  3138      * @return int
  3270      * @return int
  3139      * @psalm-suppress MixedInferredReturnType
       
  3140      * @psalm-suppress UndefinedFunction
       
  3141      */
  3271      */
  3142     public static function library_version_minor()
  3272     public static function library_version_minor()
  3143     {
  3273     {
  3144         if (self::useNewSodiumAPI()) {
  3274         if (self::useNewSodiumAPI() && defined('SODIUM_LIBRARY_MINOR_VERSION')) {
  3145             return sodium_library_version_minor();
  3275             return SODIUM_LIBRARY_MINOR_VERSION;
  3146         }
  3276         }
  3147         if (self::use_fallback('library_version_minor')) {
  3277         if (self::use_fallback('library_version_minor')) {
       
  3278             /** @psalm-suppress UndefinedFunction */
  3148             return (int) call_user_func('\\Sodium\\library_version_minor');
  3279             return (int) call_user_func('\\Sodium\\library_version_minor');
  3149         }
  3280         }
  3150         return self::LIBRARY_VERSION_MINOR;
  3281         return self::LIBRARY_VERSION_MINOR;
  3151     }
  3282     }
  3152 
  3283 
  3450         }
  3581         }
  3451         return random_int(0, 65535);
  3582         return random_int(0, 65535);
  3452     }
  3583     }
  3453 
  3584 
  3454     /**
  3585     /**
       
  3586      * @param string $p
       
  3587      * @param bool $dontFallback
       
  3588      * @return bool
       
  3589      * @throws SodiumException
       
  3590      */
       
  3591     public static function ristretto255_is_valid_point($p, $dontFallback = false)
       
  3592     {
       
  3593         if (self::useNewSodiumAPI() && !$dontFallback) {
       
  3594             return sodium_crypto_core_ristretto255_is_valid_point($p);
       
  3595         }
       
  3596         try {
       
  3597             $r = ParagonIE_Sodium_Core_Ristretto255::ristretto255_frombytes($p);
       
  3598             return $r['res'] === 0 &&
       
  3599                 ParagonIE_Sodium_Core_Ristretto255::ristretto255_point_is_canonical($p) === 1;
       
  3600         } catch (SodiumException $ex) {
       
  3601             if ($ex->getMessage() === 'S is not canonical') {
       
  3602                 return false;
       
  3603             }
       
  3604             throw $ex;
       
  3605         }
       
  3606     }
       
  3607 
       
  3608     /**
       
  3609      * @param string $p
       
  3610      * @param string $q
       
  3611      * @param bool $dontFallback
       
  3612      * @return string
       
  3613      * @throws SodiumException
       
  3614      */
       
  3615     public static function ristretto255_add($p, $q, $dontFallback = false)
       
  3616     {
       
  3617         if (self::useNewSodiumAPI() && !$dontFallback) {
       
  3618             return sodium_crypto_core_ristretto255_add($p, $q);
       
  3619         }
       
  3620         return ParagonIE_Sodium_Core_Ristretto255::ristretto255_add($p, $q);
       
  3621     }
       
  3622 
       
  3623     /**
       
  3624      * @param string $p
       
  3625      * @param string $q
       
  3626      * @param bool $dontFallback
       
  3627      * @return string
       
  3628      * @throws SodiumException
       
  3629      */
       
  3630     public static function ristretto255_sub($p, $q, $dontFallback = false)
       
  3631     {
       
  3632         if (self::useNewSodiumAPI() && !$dontFallback) {
       
  3633             return sodium_crypto_core_ristretto255_sub($p, $q);
       
  3634         }
       
  3635         return ParagonIE_Sodium_Core_Ristretto255::ristretto255_sub($p, $q);
       
  3636     }
       
  3637 
       
  3638     /**
       
  3639      * @param string $r
       
  3640      * @param bool $dontFallback
       
  3641      * @return string
       
  3642      *
       
  3643      * @throws SodiumException
       
  3644      */
       
  3645     public static function ristretto255_from_hash($r, $dontFallback = false)
       
  3646     {
       
  3647         if (self::useNewSodiumAPI() && !$dontFallback) {
       
  3648             return sodium_crypto_core_ristretto255_from_hash($r);
       
  3649         }
       
  3650         return ParagonIE_Sodium_Core_Ristretto255::ristretto255_from_hash($r);
       
  3651     }
       
  3652 
       
  3653     /**
       
  3654      * @param bool $dontFallback
       
  3655      * @return string
       
  3656      *
       
  3657      * @throws SodiumException
       
  3658      */
       
  3659     public static function ristretto255_random($dontFallback = false)
       
  3660     {
       
  3661         if (self::useNewSodiumAPI() && !$dontFallback) {
       
  3662             return sodium_crypto_core_ristretto255_random();
       
  3663         }
       
  3664         return ParagonIE_Sodium_Core_Ristretto255::ristretto255_random();
       
  3665     }
       
  3666 
       
  3667     /**
       
  3668      * @param bool $dontFallback
       
  3669      * @return string
       
  3670      *
       
  3671      * @throws SodiumException
       
  3672      */
       
  3673     public static function ristretto255_scalar_random($dontFallback = false)
       
  3674     {
       
  3675         if (self::useNewSodiumAPI() && !$dontFallback) {
       
  3676             return sodium_crypto_core_ristretto255_scalar_random();
       
  3677         }
       
  3678         return ParagonIE_Sodium_Core_Ristretto255::ristretto255_scalar_random();
       
  3679     }
       
  3680 
       
  3681     /**
       
  3682      * @param string $s
       
  3683      * @param bool $dontFallback
       
  3684      * @return string
       
  3685      * @throws SodiumException
       
  3686      */
       
  3687     public static function ristretto255_scalar_invert($s, $dontFallback = false)
       
  3688     {
       
  3689         if (self::useNewSodiumAPI() && !$dontFallback) {
       
  3690             return sodium_crypto_core_ristretto255_scalar_invert($s);
       
  3691         }
       
  3692         return ParagonIE_Sodium_Core_Ristretto255::ristretto255_scalar_invert($s);
       
  3693     }
       
  3694     /**
       
  3695      * @param string $s
       
  3696      * @param bool $dontFallback
       
  3697      * @return string
       
  3698      * @throws SodiumException
       
  3699      */
       
  3700     public static function ristretto255_scalar_negate($s, $dontFallback = false)
       
  3701     {
       
  3702         if (self::useNewSodiumAPI() && !$dontFallback) {
       
  3703             return sodium_crypto_core_ristretto255_scalar_negate($s);
       
  3704         }
       
  3705         return ParagonIE_Sodium_Core_Ristretto255::ristretto255_scalar_negate($s);
       
  3706     }
       
  3707 
       
  3708     /**
       
  3709      * @param string $s
       
  3710      * @param bool $dontFallback
       
  3711      * @return string
       
  3712      * @throws SodiumException
       
  3713      */
       
  3714     public static function ristretto255_scalar_complement($s, $dontFallback = false)
       
  3715     {
       
  3716         if (self::useNewSodiumAPI() && !$dontFallback) {
       
  3717             return sodium_crypto_core_ristretto255_scalar_complement($s);
       
  3718         }
       
  3719         return ParagonIE_Sodium_Core_Ristretto255::ristretto255_scalar_complement($s);
       
  3720     }
       
  3721 
       
  3722     /**
       
  3723      * @param string $x
       
  3724      * @param string $y
       
  3725      * @param bool $dontFallback
       
  3726      * @return string
       
  3727      * @throws SodiumException
       
  3728      */
       
  3729     public static function ristretto255_scalar_add($x, $y, $dontFallback = false)
       
  3730     {
       
  3731         if (self::useNewSodiumAPI() && !$dontFallback) {
       
  3732             return sodium_crypto_core_ristretto255_scalar_add($x, $y);
       
  3733         }
       
  3734         return ParagonIE_Sodium_Core_Ristretto255::ristretto255_scalar_add($x, $y);
       
  3735     }
       
  3736 
       
  3737     /**
       
  3738      * @param string $x
       
  3739      * @param string $y
       
  3740      * @param bool $dontFallback
       
  3741      * @return string
       
  3742      * @throws SodiumException
       
  3743      */
       
  3744     public static function ristretto255_scalar_sub($x, $y, $dontFallback = false)
       
  3745     {
       
  3746         if (self::useNewSodiumAPI() && !$dontFallback) {
       
  3747             return sodium_crypto_core_ristretto255_scalar_sub($x, $y);
       
  3748         }
       
  3749         return ParagonIE_Sodium_Core_Ristretto255::ristretto255_scalar_sub($x, $y);
       
  3750     }
       
  3751 
       
  3752     /**
       
  3753      * @param string $x
       
  3754      * @param string $y
       
  3755      * @param bool $dontFallback
       
  3756      * @return string
       
  3757      * @throws SodiumException
       
  3758      */
       
  3759     public static function ristretto255_scalar_mul($x, $y, $dontFallback = false)
       
  3760     {
       
  3761         if (self::useNewSodiumAPI() && !$dontFallback) {
       
  3762             return sodium_crypto_core_ristretto255_scalar_mul($x, $y);
       
  3763         }
       
  3764         return ParagonIE_Sodium_Core_Ristretto255::ristretto255_scalar_mul($x, $y);
       
  3765     }
       
  3766 
       
  3767     /**
       
  3768      * @param string $n
       
  3769      * @param string $p
       
  3770      * @param bool $dontFallback
       
  3771      * @return string
       
  3772      * @throws SodiumException
       
  3773      */
       
  3774     public static function scalarmult_ristretto255($n, $p, $dontFallback = false)
       
  3775     {
       
  3776         if (self::useNewSodiumAPI() && !$dontFallback) {
       
  3777             return sodium_crypto_scalarmult_ristretto255($n, $p);
       
  3778         }
       
  3779         return ParagonIE_Sodium_Core_Ristretto255::scalarmult_ristretto255($n, $p);
       
  3780     }
       
  3781 
       
  3782     /**
       
  3783      * @param string $n
       
  3784      * @param string $p
       
  3785      * @param bool $dontFallback
       
  3786      * @return string
       
  3787      * @throws SodiumException
       
  3788      */
       
  3789     public static function scalarmult_ristretto255_base($n, $dontFallback = false)
       
  3790     {
       
  3791         if (self::useNewSodiumAPI() && !$dontFallback) {
       
  3792             return sodium_crypto_scalarmult_ristretto255_base($n);
       
  3793         }
       
  3794         return ParagonIE_Sodium_Core_Ristretto255::scalarmult_ristretto255_base($n);
       
  3795     }
       
  3796 
       
  3797     /**
       
  3798      * @param string $s
       
  3799      * @param bool $dontFallback
       
  3800      * @return string
       
  3801      * @throws SodiumException
       
  3802      */
       
  3803     public static function ristretto255_scalar_reduce($s, $dontFallback = false)
       
  3804     {
       
  3805         if (self::useNewSodiumAPI() && !$dontFallback) {
       
  3806             return sodium_crypto_core_ristretto255_scalar_reduce($s);
       
  3807         }
       
  3808         return ParagonIE_Sodium_Core_Ristretto255::sc_reduce($s);
       
  3809     }
       
  3810 
       
  3811     /**
  3455      * Runtime testing method for 32-bit platforms.
  3812      * Runtime testing method for 32-bit platforms.
  3456      *
  3813      *
  3457      * Usage: If runtime_speed_test() returns FALSE, then our 32-bit
  3814      * Usage: If runtime_speed_test() returns FALSE, then our 32-bit
  3458      *        implementation is to slow to use safely without risking timeouts.
  3815      *        implementation is to slow to use safely without risking timeouts.
  3459      *        If this happens, install sodium from PECL to get acceptable
  3816      *        If this happens, install sodium from PECL to get acceptable
  3486         $diff = (int) ceil(($end - $start) * 1000);
  3843         $diff = (int) ceil(($end - $start) * 1000);
  3487         return $diff < $maxTimeout;
  3844         return $diff < $maxTimeout;
  3488     }
  3845     }
  3489 
  3846 
  3490     /**
  3847     /**
       
  3848      * Add two numbers (little-endian unsigned), storing the value in the first
       
  3849      * parameter.
       
  3850      *
       
  3851      * This mutates $val.
       
  3852      *
       
  3853      * @param string $val
       
  3854      * @param string $addv
       
  3855      * @return void
       
  3856      * @throws SodiumException
       
  3857      */
       
  3858     public static function sub(&$val, $addv)
       
  3859     {
       
  3860         $val_len = ParagonIE_Sodium_Core_Util::strlen($val);
       
  3861         $addv_len = ParagonIE_Sodium_Core_Util::strlen($addv);
       
  3862         if ($val_len !== $addv_len) {
       
  3863             throw new SodiumException('values must have the same length');
       
  3864         }
       
  3865         $A = ParagonIE_Sodium_Core_Util::stringToIntArray($val);
       
  3866         $B = ParagonIE_Sodium_Core_Util::stringToIntArray($addv);
       
  3867 
       
  3868         $c = 0;
       
  3869         for ($i = 0; $i < $val_len; $i++) {
       
  3870             $c = ($A[$i] - $B[$i] - $c);
       
  3871             $A[$i] = ($c & 0xff);
       
  3872             $c = ($c >> 8) & 1;
       
  3873         }
       
  3874         $val = ParagonIE_Sodium_Core_Util::intArrayToString($A);
       
  3875     }
       
  3876 
       
  3877     /**
  3491      * This emulates libsodium's version_string() function, except ours is
  3878      * This emulates libsodium's version_string() function, except ours is
  3492      * prefixed with 'polyfill-'.
  3879      * prefixed with 'polyfill-'.
  3493      *
  3880      *
  3494      * @return string
  3881      * @return string
  3495      * @psalm-suppress MixedInferredReturnType
  3882      * @psalm-suppress MixedInferredReturnType