Skip to content

Instantly share code, notes, and snippets.

@oschonrock
Last active December 7, 2017 11:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save oschonrock/a3e0490e0d410de2803a0e1ce762026f to your computer and use it in GitHub Desktop.
Save oschonrock/a3e0490e0d410de2803a0e1ce762026f to your computer and use it in GitHub Desktop.
pecl-libsodium to php72-sodium compat lib
#!/usr/bin/env php
<?php
/*
* generates the code for sodium_compat.php
*/
define('BASE', dirname(dirname(__FILE__)) . '/');
$lib = '<?php
/*
* pecl-libsodium to php72-sodium compat lib
*
* gist: https://gist.github.com/oschonrock/a3e0490e0d410de2803a0e1ce762026f
*
* The purpose of this small compat lib is to make the migration from pecl-libsodium to php72-sodium easier
* the RFC process makign Sodium a core php extension: https://wiki.php.net/rfc/libsodium
* decided to use global namespace for the functions and constants provided by the new php72-sodium
*
* This creates some small problems for those who were already using pecl-lisodium with its \Sodium\ functions and constants
*
* Usually when ugrading php on a server, the code changes are done ahead of upgrade time and then the sysadmin upgrades the machine.
* Because the upgraded code (using sodium_* functions and SODIUM_* constants) will not run with pecl-lisodium, this lib provides a compat layer.
*
* It wraps all the old \Sodium\ functions and constants in sodium_* and SODIUM_* new style functions and constants
*
* How to use:
* 1. Just require this file in your application bootstrap, before you upgrade to php72 and the new php72-sodium extension
* 2. make your code compat with the new signatures (ie change all your calls to \Sodium\* to (sodium_|SODIUM_)* )
* 3. commit and deploy. Your new code can run against the old pecl extension now
* 4. When the sysadmin upgrades to php72 and ext-sodium, it will already "magically" work
*
* \Sodium\randombytes_buf (particularly usesful for people upgrading from php56)
* If you were using this rather than the core php function random_bytes(), then this lib helps with that as well
* it is not quite part of the above pattern, because the new php72-sodium extension does not include \Sodium\randombytes_buf
* you are supposed to use random_bytes() now. But if you still have php56 then you were probably using \Sodium\randombytes_buf
* so there is a wrapper for that as well.
*
* This code was generated by a script which uses get_defined_constants() and get_defined_functions() and then "writes" the wrappers
* That generator script is also part of this gist.
*
* LICENSE WhateverYouWantItToBe
* author: oliver at schonrocks dot com
*
*/
if (!function_exists(\'sodium_crypto_box_open\') && function_exists(\'\Sodium\crypto_box_open\'))
{
';
foreach (get_defined_constants() as $const => $value)
{
if ((strpos($const, 'Sodium\\') === 0))
{
$gconst = strtoupper(str_replace('Sodium\\', 'Sodium_', $const));
$lib .= ' define(\'' . $gconst . '\', \\' . $const . ');' . "\n";
}
}
$lib .= "\n\n";
foreach (get_defined_functions()['internal'] as $func)
{
if ((strpos($func, 'sodium\\') === 0))
{
$gfunc = str_replace('sodium\\', 'sodium_', $func);
$lib .= ' function ' . $gfunc . '(...$p) { return \\' . ucfirst($func) . '(...$p); }' . "\n";
}
}
$lib .= '
}
if (!function_exists(\'random_bytes\') && function_exists(\'\Sodium\randombytes_buf\'))
{
// and migrate to the generic crypto stream random generator
function random_bytes(...$p) { return \Sodium\randombytes_buf(...$p); }
}
';
// just build once
file_put_contents(BASE . 'lib/sodium_compat.php', $lib);
// test
require(BASE . 'lib/sodium_compat.php');
var_dump(SODIUM_CRYPTO_AUTH_BYTES);
$key = random_bytes(SODIUM_CRYPTO_AUTH_KEYBYTES);
var_dump(bin2hex($key));
$msg = 'some garbage messgae';
var_dump(sodium_crypto_auth_verify(sodium_crypto_auth($msg, $key), $msg, $key));
var_dump(SODIUM_CRYPTO_AUTH_KEYBYTES);
$bad_sig = random_bytes(SODIUM_CRYPTO_AUTH_BYTES);
var_dump(bin2hex($bad_sig));
var_dump(sodium_crypto_auth_verify($bad_sig, $msg, $key));
<?php
/*
* pecl-libsodium to php72-sodium compat lib
*
* The purpose of this small compat lib is to make the migration from pecl-libsodium to php72-sodium easier
* the RFC process makign Sodium a core php extension: https://wiki.php.net/rfc/libsodium
* decided to use global namespace for the functions and constants provided by the new php72-sodium
*
* This creates some small problems for those who were already using pecl-lisodium with its \Sodium\ functions and constants
*
* Usually when ugrading php on a server, the code changes are done ahead of upgrade time and then the sysadmin upgrades the machine.
* Because the upgraded code (using sodium_* functions and SODIUM_* constants) will not run with pecl-lisodium, this lib provides a compat layer.
*
* It wraps all the old \Sodium\ functions and constants in sodium_* and SODIUM_* new style functions and constants
*
* How to use:
* 1. Just require this file in your application bootstrap, before you upgrade to php72 and the new php72-sodium extension
* 2. make your code compat with the new signatures (ie change all your calls to \Sodium\* to (sodium_|SODIUM_)* )
* 3. commit and deploy. Your new code can run against the old pecl extension now
* 4. When the sysadmin upgrades to php72 and ext-sodium, it will already "magically" work
*
* \Sodium\randombytes_buf (particularly usesful for people upgrading from php56)
* If you were using this rather than the core php function random_bytes(), then this lib helps with that as well
* it is not quite part of the above pattern, because the new php72-sodium extension does not include \Sodium\randombytes_buf
* you are supposed to use random_bytes() now. But if you still have php56 then you were probably using \Sodium\randombytes_buf
* so there is a wrapper for that as well.
*
* This code was generated by a script which uses get_defined_constants() and get_defined_functions() and then "writes" the wrappers
* That generator script is also part of this gist.
*
* LICENSE WhateverYouWantItToBe
* author: oliver at schonrocks dot com
*
*/
if (!function_exists('sodium_crypto_box_open') && function_exists('\Sodium\crypto_box_open'))
{
define('SODIUM_CRYPTO_AEAD_AES256GCM_KEYBYTES', \Sodium\CRYPTO_AEAD_AES256GCM_KEYBYTES);
define('SODIUM_CRYPTO_AEAD_AES256GCM_NSECBYTES', \Sodium\CRYPTO_AEAD_AES256GCM_NSECBYTES);
define('SODIUM_CRYPTO_AEAD_AES256GCM_NPUBBYTES', \Sodium\CRYPTO_AEAD_AES256GCM_NPUBBYTES);
define('SODIUM_CRYPTO_AEAD_AES256GCM_ABYTES', \Sodium\CRYPTO_AEAD_AES256GCM_ABYTES);
define('SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_KEYBYTES', \Sodium\CRYPTO_AEAD_CHACHA20POLY1305_KEYBYTES);
define('SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_NSECBYTES', \Sodium\CRYPTO_AEAD_CHACHA20POLY1305_NSECBYTES);
define('SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_NPUBBYTES', \Sodium\CRYPTO_AEAD_CHACHA20POLY1305_NPUBBYTES);
define('SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_ABYTES', \Sodium\CRYPTO_AEAD_CHACHA20POLY1305_ABYTES);
define('SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_KEYBYTES', \Sodium\CRYPTO_AEAD_CHACHA20POLY1305_IETF_KEYBYTES);
define('SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NSECBYTES', \Sodium\CRYPTO_AEAD_CHACHA20POLY1305_IETF_NSECBYTES);
define('SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES', \Sodium\CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES);
define('SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_ABYTES', \Sodium\CRYPTO_AEAD_CHACHA20POLY1305_IETF_ABYTES);
define('SODIUM_CRYPTO_AUTH_BYTES', \Sodium\CRYPTO_AUTH_BYTES);
define('SODIUM_CRYPTO_AUTH_KEYBYTES', \Sodium\CRYPTO_AUTH_KEYBYTES);
define('SODIUM_CRYPTO_BOX_SEALBYTES', \Sodium\CRYPTO_BOX_SEALBYTES);
define('SODIUM_CRYPTO_BOX_SECRETKEYBYTES', \Sodium\CRYPTO_BOX_SECRETKEYBYTES);
define('SODIUM_CRYPTO_BOX_PUBLICKEYBYTES', \Sodium\CRYPTO_BOX_PUBLICKEYBYTES);
define('SODIUM_CRYPTO_BOX_KEYPAIRBYTES', \Sodium\CRYPTO_BOX_KEYPAIRBYTES);
define('SODIUM_CRYPTO_BOX_MACBYTES', \Sodium\CRYPTO_BOX_MACBYTES);
define('SODIUM_CRYPTO_BOX_NONCEBYTES', \Sodium\CRYPTO_BOX_NONCEBYTES);
define('SODIUM_CRYPTO_BOX_SEEDBYTES', \Sodium\CRYPTO_BOX_SEEDBYTES);
define('SODIUM_CRYPTO_KX_BYTES', \Sodium\CRYPTO_KX_BYTES);
define('SODIUM_CRYPTO_KX_PUBLICKEYBYTES', \Sodium\CRYPTO_KX_PUBLICKEYBYTES);
define('SODIUM_CRYPTO_KX_SECRETKEYBYTES', \Sodium\CRYPTO_KX_SECRETKEYBYTES);
define('SODIUM_CRYPTO_GENERICHASH_BYTES', \Sodium\CRYPTO_GENERICHASH_BYTES);
define('SODIUM_CRYPTO_GENERICHASH_BYTES_MIN', \Sodium\CRYPTO_GENERICHASH_BYTES_MIN);
define('SODIUM_CRYPTO_GENERICHASH_BYTES_MAX', \Sodium\CRYPTO_GENERICHASH_BYTES_MAX);
define('SODIUM_CRYPTO_GENERICHASH_KEYBYTES', \Sodium\CRYPTO_GENERICHASH_KEYBYTES);
define('SODIUM_CRYPTO_GENERICHASH_KEYBYTES_MIN', \Sodium\CRYPTO_GENERICHASH_KEYBYTES_MIN);
define('SODIUM_CRYPTO_GENERICHASH_KEYBYTES_MAX', \Sodium\CRYPTO_GENERICHASH_KEYBYTES_MAX);
define('SODIUM_CRYPTO_PWHASH_SALTBYTES', \Sodium\CRYPTO_PWHASH_SALTBYTES);
define('SODIUM_CRYPTO_PWHASH_STRPREFIX', \Sodium\CRYPTO_PWHASH_STRPREFIX);
define('SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE', \Sodium\CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE);
define('SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE', \Sodium\CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE);
define('SODIUM_CRYPTO_PWHASH_OPSLIMIT_MODERATE', \Sodium\CRYPTO_PWHASH_OPSLIMIT_MODERATE);
define('SODIUM_CRYPTO_PWHASH_MEMLIMIT_MODERATE', \Sodium\CRYPTO_PWHASH_MEMLIMIT_MODERATE);
define('SODIUM_CRYPTO_PWHASH_OPSLIMIT_SENSITIVE', \Sodium\CRYPTO_PWHASH_OPSLIMIT_SENSITIVE);
define('SODIUM_CRYPTO_PWHASH_MEMLIMIT_SENSITIVE', \Sodium\CRYPTO_PWHASH_MEMLIMIT_SENSITIVE);
define('SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_SALTBYTES', \Sodium\CRYPTO_PWHASH_SCRYPTSALSA208SHA256_SALTBYTES);
define('SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_STRPREFIX', \Sodium\CRYPTO_PWHASH_SCRYPTSALSA208SHA256_STRPREFIX);
define('SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_OPSLIMIT_INTERACTIVE', \Sodium\CRYPTO_PWHASH_SCRYPTSALSA208SHA256_OPSLIMIT_INTERACTIVE);
define('SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_MEMLIMIT_INTERACTIVE', \Sodium\CRYPTO_PWHASH_SCRYPTSALSA208SHA256_MEMLIMIT_INTERACTIVE);
define('SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_OPSLIMIT_SENSITIVE', \Sodium\CRYPTO_PWHASH_SCRYPTSALSA208SHA256_OPSLIMIT_SENSITIVE);
define('SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_MEMLIMIT_SENSITIVE', \Sodium\CRYPTO_PWHASH_SCRYPTSALSA208SHA256_MEMLIMIT_SENSITIVE);
define('SODIUM_CRYPTO_SCALARMULT_BYTES', \Sodium\CRYPTO_SCALARMULT_BYTES);
define('SODIUM_CRYPTO_SCALARMULT_SCALARBYTES', \Sodium\CRYPTO_SCALARMULT_SCALARBYTES);
define('SODIUM_CRYPTO_SHORTHASH_BYTES', \Sodium\CRYPTO_SHORTHASH_BYTES);
define('SODIUM_CRYPTO_SHORTHASH_KEYBYTES', \Sodium\CRYPTO_SHORTHASH_KEYBYTES);
define('SODIUM_CRYPTO_SECRETBOX_KEYBYTES', \Sodium\CRYPTO_SECRETBOX_KEYBYTES);
define('SODIUM_CRYPTO_SECRETBOX_MACBYTES', \Sodium\CRYPTO_SECRETBOX_MACBYTES);
define('SODIUM_CRYPTO_SECRETBOX_NONCEBYTES', \Sodium\CRYPTO_SECRETBOX_NONCEBYTES);
define('SODIUM_CRYPTO_SIGN_BYTES', \Sodium\CRYPTO_SIGN_BYTES);
define('SODIUM_CRYPTO_SIGN_SEEDBYTES', \Sodium\CRYPTO_SIGN_SEEDBYTES);
define('SODIUM_CRYPTO_SIGN_PUBLICKEYBYTES', \Sodium\CRYPTO_SIGN_PUBLICKEYBYTES);
define('SODIUM_CRYPTO_SIGN_SECRETKEYBYTES', \Sodium\CRYPTO_SIGN_SECRETKEYBYTES);
define('SODIUM_CRYPTO_SIGN_KEYPAIRBYTES', \Sodium\CRYPTO_SIGN_KEYPAIRBYTES);
define('SODIUM_CRYPTO_STREAM_NONCEBYTES', \Sodium\CRYPTO_STREAM_NONCEBYTES);
define('SODIUM_CRYPTO_STREAM_KEYBYTES', \Sodium\CRYPTO_STREAM_KEYBYTES);
function sodium_crypto_aead_aes256gcm_is_available(...$p) { return \Sodium\crypto_aead_aes256gcm_is_available(...$p); }
function sodium_crypto_aead_aes256gcm_decrypt(...$p) { return \Sodium\crypto_aead_aes256gcm_decrypt(...$p); }
function sodium_crypto_aead_aes256gcm_encrypt(...$p) { return \Sodium\crypto_aead_aes256gcm_encrypt(...$p); }
function sodium_crypto_aead_chacha20poly1305_decrypt(...$p) { return \Sodium\crypto_aead_chacha20poly1305_decrypt(...$p); }
function sodium_crypto_aead_chacha20poly1305_encrypt(...$p) { return \Sodium\crypto_aead_chacha20poly1305_encrypt(...$p); }
function sodium_crypto_aead_chacha20poly1305_ietf_decrypt(...$p) { return \Sodium\crypto_aead_chacha20poly1305_ietf_decrypt(...$p); }
function sodium_crypto_aead_chacha20poly1305_ietf_encrypt(...$p) { return \Sodium\crypto_aead_chacha20poly1305_ietf_encrypt(...$p); }
function sodium_crypto_auth(...$p) { return \Sodium\crypto_auth(...$p); }
function sodium_crypto_auth_verify(...$p) { return \Sodium\crypto_auth_verify(...$p); }
function sodium_crypto_box(...$p) { return \Sodium\crypto_box(...$p); }
function sodium_crypto_box_keypair(...$p) { return \Sodium\crypto_box_keypair(...$p); }
function sodium_crypto_box_seed_keypair(...$p) { return \Sodium\crypto_box_seed_keypair(...$p); }
function sodium_crypto_box_keypair_from_secretkey_and_publickey(...$p) { return \Sodium\crypto_box_keypair_from_secretkey_and_publickey(...$p); }
function sodium_crypto_box_open(...$p) { return \Sodium\crypto_box_open(...$p); }
function sodium_crypto_box_publickey(...$p) { return \Sodium\crypto_box_publickey(...$p); }
function sodium_crypto_box_publickey_from_secretkey(...$p) { return \Sodium\crypto_box_publickey_from_secretkey(...$p); }
function sodium_crypto_box_seal(...$p) { return \Sodium\crypto_box_seal(...$p); }
function sodium_crypto_box_seal_open(...$p) { return \Sodium\crypto_box_seal_open(...$p); }
function sodium_crypto_box_secretkey(...$p) { return \Sodium\crypto_box_secretkey(...$p); }
function sodium_crypto_kx(...$p) { return \Sodium\crypto_kx(...$p); }
function sodium_crypto_generichash(...$p) { return \Sodium\crypto_generichash(...$p); }
function sodium_crypto_generichash_init(...$p) { return \Sodium\crypto_generichash_init(...$p); }
function sodium_crypto_generichash_update(...$p) { return \Sodium\crypto_generichash_update(...$p); }
function sodium_crypto_generichash_final(...$p) { return \Sodium\crypto_generichash_final(...$p); }
function sodium_crypto_pwhash(...$p) { return \Sodium\crypto_pwhash(...$p); }
function sodium_crypto_pwhash_str(...$p) { return \Sodium\crypto_pwhash_str(...$p); }
function sodium_crypto_pwhash_str_verify(...$p) { return \Sodium\crypto_pwhash_str_verify(...$p); }
function sodium_crypto_pwhash_scryptsalsa208sha256(...$p) { return \Sodium\crypto_pwhash_scryptsalsa208sha256(...$p); }
function sodium_crypto_pwhash_scryptsalsa208sha256_str(...$p) { return \Sodium\crypto_pwhash_scryptsalsa208sha256_str(...$p); }
function sodium_crypto_pwhash_scryptsalsa208sha256_str_verify(...$p) { return \Sodium\crypto_pwhash_scryptsalsa208sha256_str_verify(...$p); }
function sodium_crypto_scalarmult(...$p) { return \Sodium\crypto_scalarmult(...$p); }
function sodium_crypto_secretbox(...$p) { return \Sodium\crypto_secretbox(...$p); }
function sodium_crypto_secretbox_open(...$p) { return \Sodium\crypto_secretbox_open(...$p); }
function sodium_crypto_shorthash(...$p) { return \Sodium\crypto_shorthash(...$p); }
function sodium_crypto_sign(...$p) { return \Sodium\crypto_sign(...$p); }
function sodium_crypto_sign_detached(...$p) { return \Sodium\crypto_sign_detached(...$p); }
function sodium_crypto_sign_ed25519_pk_to_curve25519(...$p) { return \Sodium\crypto_sign_ed25519_pk_to_curve25519(...$p); }
function sodium_crypto_sign_ed25519_sk_to_curve25519(...$p) { return \Sodium\crypto_sign_ed25519_sk_to_curve25519(...$p); }
function sodium_crypto_sign_keypair(...$p) { return \Sodium\crypto_sign_keypair(...$p); }
function sodium_crypto_sign_keypair_from_secretkey_and_publickey(...$p) { return \Sodium\crypto_sign_keypair_from_secretkey_and_publickey(...$p); }
function sodium_crypto_sign_open(...$p) { return \Sodium\crypto_sign_open(...$p); }
function sodium_crypto_sign_publickey(...$p) { return \Sodium\crypto_sign_publickey(...$p); }
function sodium_crypto_sign_secretkey(...$p) { return \Sodium\crypto_sign_secretkey(...$p); }
function sodium_crypto_sign_publickey_from_secretkey(...$p) { return \Sodium\crypto_sign_publickey_from_secretkey(...$p); }
function sodium_crypto_sign_seed_keypair(...$p) { return \Sodium\crypto_sign_seed_keypair(...$p); }
function sodium_crypto_sign_verify_detached(...$p) { return \Sodium\crypto_sign_verify_detached(...$p); }
function sodium_crypto_stream(...$p) { return \Sodium\crypto_stream(...$p); }
function sodium_crypto_stream_xor(...$p) { return \Sodium\crypto_stream_xor(...$p); }
function sodium_randombytes_buf(...$p) { return \Sodium\randombytes_buf(...$p); }
function sodium_randombytes_random16(...$p) { return \Sodium\randombytes_random16(...$p); }
function sodium_randombytes_uniform(...$p) { return \Sodium\randombytes_uniform(...$p); }
function sodium_bin2hex(...$p) { return \Sodium\bin2hex(...$p); }
function sodium_compare(...$p) { return \Sodium\compare(...$p); }
function sodium_hex2bin(...$p) { return \Sodium\hex2bin(...$p); }
function sodium_increment(...$p) { return \Sodium\increment(...$p); }
function sodium_add(...$p) { return \Sodium\add(...$p); }
function sodium_library_version_major(...$p) { return \Sodium\library_version_major(...$p); }
function sodium_library_version_minor(...$p) { return \Sodium\library_version_minor(...$p); }
function sodium_memcmp(...$p) { return \Sodium\memcmp(...$p); }
function sodium_memzero(...$p) { return \Sodium\memzero(...$p); }
function sodium_version_string(...$p) { return \Sodium\version_string(...$p); }
function sodium_crypto_scalarmult_base(...$p) { return \Sodium\crypto_scalarmult_base(...$p); }
}
if (!function_exists('random_bytes') && function_exists('\Sodium\randombytes_buf'))
{
// and migrate to the generic crypto stream random generator
function random_bytes(...$p) { return \Sodium\randombytes_buf(...$p); }
}
@oschonrock
Copy link
Author

oschonrock commented Dec 7, 2017

This file https://github.com/paragonie/sodium_compat/blob/master/lib/php72compat.php
in the (larger & more complete) https://github.com/paragonie/sodium_compat Paragonie Compatibility library does something very similar without using code generation, the "..." operator and calling the bigger ParagonIE_Sodium_Compat::* wrappers.

Your mileage may vary.

If you want a slim (and temporary) compat layer, this gist will probably do the job.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment