get_bytes( SODIUM_CRYPTO_SECRETBOX_NONCEBYTES ); $fn = ($key_usage == self::single_key) ? "sodium_crypto_secretbox" : "sodium_crypto_box"; $cipher = base64_encode( $nonce . $fn( $message, $nonce, base64_decode($key) ) ); sodium_memzero($message); sodium_memzero($key); return $cipher; } public static function safe_decrypt( string $encrypted, string $key, bool $key_usage = self::single_key ): string | false { $decoded = base64_decode($encrypted); if ($decoded === false) { throw new Exception('Unable to decode'); } if (mb_strlen($decoded, '8bit') < (SODIUM_CRYPTO_SECRETBOX_NONCEBYTES + SODIUM_CRYPTO_SECRETBOX_MACBYTES)) { throw new Exception('Message was truncated'); } $nonce = mb_substr($decoded, 0, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, '8bit'); $ciphertext = mb_substr($decoded, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, null, '8bit'); $fn = ($key_usage == self::single_key) ? "sodium_crypto_secretbox_open" : "sodium_crypto_box_open"; $plain = $fn( $ciphertext, $nonce, base64_decode($key) ); sodium_memzero($ciphertext); sodium_memzero($key); return $plain; } public static function make_user_box_kp() { return sodium_crypto_box_keypair(); } public static function make_user_sign_kp() { return sodium_crypto_sign_keypair(); } public static function get_user_box_secret_key(string $from_make_user_box_kp): string { return base64_encode(sodium_crypto_box_secretkey($from_make_user_box_kp)); } public static function get_user_box_public_key(string $from_make_user_box_kp): string { return base64_encode(sodium_crypto_box_publickey($from_make_user_box_kp)); } public static function get_user_sign_secret_key(string $from_make_user_sign_secret_kp): string { return sodium_crypto_sign_secretkey($from_make_user_sign_secret_kp); } public static function get_user_sign_public_key(string $from_make_user_sign_public_kp): string { return sodium_crypto_sign_secretkey($from_make_user_sign_public_kp); } public static function box_reassemble_keypair( string $from_get_userA_box_secret_key, string $from_get_userB_box_public_key ): string { return base64_encode(sodium_crypto_box_keypair_from_secretkey_and_publickey( base64_decode($from_get_userA_box_secret_key), base64_decode($from_get_userB_box_public_key) )); } public static function sign_message(string $message, string $user_sign_secretkey): string { return sodium_crypto_sign( $message, $user_sign_secretkey ); } public static function get_signed_message(string $signed_message, string $user_sign_publickey): string | false { return sodium_crypto_sign_open( $signed_message, $user_sign_publickey ); } public static function make_just_signature(string $message, string $user_sign_secretkey): string { return sodium_crypto_sign_detached( $message, $user_sign_secretkey ); } public static function is_a_valid_signature( string $signature, string $message, string $user_sign_public_key ): bool { if ( sodium_crypto_sign_verify_detached( $signature, $message, $user_sign_publickey ) ) { return true; } else { return false; } } public static function a_single_key_maker(): string { $rnd = new \tts\random_engine(); return base64_encode($rnd->get_bytes(SODIUM_CRYPTO_SECRETBOX_KEYBYTES)); } /* * Extract the public key from the secret key */ public static function sign_publickey_from_secretkey(string $key) { return sodium_crypto_sign_publickey_from_secretkey($key); } public static function increment_sequential_nonce($x) { return sodium_increment($x); // The obtain the next nonce } // Should you Proceed with crypto_box decryption, if true go ahead do it. public static function is_safe_to_decode($message_nonce, $expected_nonce): bool { return (sodium_compare($message_nonce, $expected_nonce) === 0); } /* * Sometimes you don't need to hide the contents of a message with encryption, * but you still want to ensure that nobody on the network can tamper with * it. For example, if you want to eschew server-side session storage and * instead use HTTP cookies as your storage mechanism. */ public static function sign_outbound_message_only(string $message, string $key): string { $mac = sodium_crypto_auth($message, $key); return $mac . "@@" . $message; } public static function is_valid_inbound_message(string $message, string $key): bool { $a = explode("@@", $message, 2); $mac = $a[0]; $old_message = $a[1]; $ret_bool = (sodium_crypto_auth_verify($mac, $old_message, $key)); if ($ret_bool === false) { sodium_memzero($key); throw new \Exception("Malformed message or invalid MAC"); } return $ret_bool; } } /* * Usage: * $key = tts\services\paragon_crypto\crypto::a_single_key_maker(); $enc = tts\services\paragon_crypto\crypto::safe_encrypt('Encrypt This String...', $key, \tts\services\paragon_crypto\crypto::single_key); echo $enc . "
"; $dec = \tts\services\paragon_crypto\crypto::safe_decrypt($enc, $key, \tts\services\paragon_crypto\crypto::single_key); echo $dec . "
";; // -------------------- $key_pair_Alice = \tts\services\paragon_crypto\crypto::make_user_box_kp(); $secret_Alice = \tts\services\paragon_crypto\crypto::get_user_box_secret_key($key_pair_Alice); $public_Alice = \tts\services\paragon_crypto\crypto::get_user_box_public_key($key_pair_Alice); $key_pair_Bob = \tts\services\paragon_crypto\crypto::make_user_box_kp(); $secret_Bob = \tts\services\paragon_crypto\crypto::get_user_box_secret_key($key_pair_Bob); $public_Bob = \tts\services\paragon_crypto\crypto::get_user_box_public_key($key_pair_Bob); $kA = \tts\services\paragon_crypto\crypto::box_reassemble_keypair($secret_Alice, $public_Bob); $enc = \tts\services\paragon_crypto\crypto::safe_encrypt('Encrypt This String2...', $kA, \tts\services\paragon_crypto\crypto::multiple_keys); echo $enc . "
"; $kB = \tts\services\paragon_crypto\crypto::box_reassemble_keypair($secret_Bob, $public_Alice); $dec = \tts\services\paragon_crypto\crypto::safe_decrypt($enc, $kB, \tts\services\paragon_crypto\crypto::multiple_keys); echo $dec; */