Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like ParagonIE_Sodium_Crypto often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use ParagonIE_Sodium_Crypto, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
15 | abstract class ParagonIE_Sodium_Crypto |
||
16 | { |
||
17 | const aead_chacha20poly1305_KEYBYTES = 32; |
||
18 | const aead_chacha20poly1305_NSECBYTES = 0; |
||
19 | const aead_chacha20poly1305_NPUBBYTES = 8; |
||
20 | const aead_chacha20poly1305_ABYTES = 16; |
||
21 | |||
22 | const aead_chacha20poly1305_IETF_KEYBYTES = 32; |
||
23 | const aead_chacha20poly1305_IETF_NSECBYTES = 0; |
||
24 | const aead_chacha20poly1305_IETF_NPUBBYTES = 12; |
||
25 | const aead_chacha20poly1305_IETF_ABYTES = 16; |
||
26 | |||
27 | const aead_xchacha20poly1305_IETF_KEYBYTES = 32; |
||
28 | const aead_xchacha20poly1305_IETF_NSECBYTES = 0; |
||
29 | const aead_xchacha20poly1305_IETF_NPUBBYTES = 24; |
||
30 | const aead_xchacha20poly1305_IETF_ABYTES = 16; |
||
31 | |||
32 | const box_curve25519xsalsa20poly1305_SEEDBYTES = 32; |
||
33 | const box_curve25519xsalsa20poly1305_PUBLICKEYBYTES = 32; |
||
34 | const box_curve25519xsalsa20poly1305_SECRETKEYBYTES = 32; |
||
35 | const box_curve25519xsalsa20poly1305_BEFORENMBYTES = 32; |
||
36 | const box_curve25519xsalsa20poly1305_NONCEBYTES = 24; |
||
37 | const box_curve25519xsalsa20poly1305_MACBYTES = 16; |
||
38 | const box_curve25519xsalsa20poly1305_BOXZEROBYTES = 16; |
||
39 | const box_curve25519xsalsa20poly1305_ZEROBYTES = 32; |
||
40 | |||
41 | const onetimeauth_poly1305_BYTES = 16; |
||
42 | const onetimeauth_poly1305_KEYBYTES = 32; |
||
43 | |||
44 | const secretbox_xsalsa20poly1305_KEYBYTES = 32; |
||
45 | const secretbox_xsalsa20poly1305_NONCEBYTES = 24; |
||
46 | const secretbox_xsalsa20poly1305_MACBYTES = 16; |
||
47 | const secretbox_xsalsa20poly1305_BOXZEROBYTES = 16; |
||
48 | const secretbox_xsalsa20poly1305_ZEROBYTES = 32; |
||
49 | |||
50 | const secretbox_xchacha20poly1305_KEYBYTES = 32; |
||
51 | const secretbox_xchacha20poly1305_NONCEBYTES = 24; |
||
52 | const secretbox_xchacha20poly1305_MACBYTES = 16; |
||
53 | const secretbox_xchacha20poly1305_BOXZEROBYTES = 16; |
||
54 | const secretbox_xchacha20poly1305_ZEROBYTES = 32; |
||
55 | |||
56 | const stream_salsa20_KEYBYTES = 32; |
||
57 | |||
58 | /** |
||
59 | * AEAD Decryption with ChaCha20-Poly1305 |
||
60 | * |
||
61 | * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. |
||
62 | * |
||
63 | * @param string $message |
||
64 | * @param string $ad |
||
65 | * @param string $nonce |
||
66 | * @param string $key |
||
67 | * @return string |
||
68 | * @throws Error |
||
69 | */ |
||
70 | View Code Duplication | public static function aead_chacha20poly1305_decrypt( |
|
128 | |||
129 | /** |
||
130 | * AEAD Encryption with ChaCha20-Poly1305 |
||
131 | * |
||
132 | * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. |
||
133 | * |
||
134 | * @param string $message |
||
135 | * @param string $ad |
||
136 | * @param string $nonce |
||
137 | * @param string $key |
||
138 | * @return string |
||
139 | */ |
||
140 | View Code Duplication | public static function aead_chacha20poly1305_encrypt( |
|
179 | |||
180 | /** |
||
181 | * AEAD Decryption with ChaCha20-Poly1305, IETF mode (96-bit nonce) |
||
182 | * |
||
183 | * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. |
||
184 | * |
||
185 | * @param string $message |
||
186 | * @param string $ad |
||
187 | * @param string $nonce |
||
188 | * @param string $key |
||
189 | * @return string |
||
190 | * @throws Error |
||
191 | */ |
||
192 | View Code Duplication | public static function aead_chacha20poly1305_ietf_decrypt( |
|
256 | |||
257 | /** |
||
258 | * AEAD Encryption with ChaCha20-Poly1305, IETF mode (96-bit nonce) |
||
259 | * |
||
260 | * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. |
||
261 | * |
||
262 | * @param string $message |
||
263 | * @param string $ad |
||
264 | * @param string $nonce |
||
265 | * @param string $key |
||
266 | * @return string |
||
267 | */ |
||
268 | View Code Duplication | public static function aead_chacha20poly1305_ietf_encrypt( |
|
309 | |||
310 | /** |
||
311 | * AEAD Decryption with ChaCha20-Poly1305, IETF mode (96-bit nonce) |
||
312 | * |
||
313 | * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. |
||
314 | * |
||
315 | * @param string $message |
||
316 | * @param string $ad |
||
317 | * @param string $nonce |
||
318 | * @param string $key |
||
319 | * @return string |
||
320 | * @throws Error |
||
321 | */ |
||
322 | public static function aead_xchacha20poly1305_ietf_decrypt( |
||
337 | |||
338 | /** |
||
339 | * AEAD Encryption with ChaCha20-Poly1305, IETF mode (96-bit nonce) |
||
340 | * |
||
341 | * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. |
||
342 | * |
||
343 | * @param string $message |
||
344 | * @param string $ad |
||
345 | * @param string $nonce |
||
346 | * @param string $key |
||
347 | * @return string |
||
348 | */ |
||
349 | View Code Duplication | public static function aead_xchacha20poly1305_ietf_encrypt( |
|
364 | |||
365 | /** |
||
366 | * HMAC-SHA-512-256 (a.k.a. the leftmost 256 bits of HMAC-SHA-512) |
||
367 | * |
||
368 | * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. |
||
369 | * |
||
370 | * @param string $message |
||
371 | * @param string $key |
||
372 | * @return string |
||
373 | */ |
||
374 | public static function auth($message, $key) |
||
382 | |||
383 | /** |
||
384 | * HMAC-SHA-512-256 validation. Constant-time via hash_equals(). |
||
385 | * |
||
386 | * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. |
||
387 | * |
||
388 | * @param string $mac |
||
389 | * @param string $message |
||
390 | * @param string $key |
||
391 | * @return bool |
||
392 | */ |
||
393 | public static function auth_verify($mac, $message, $key) |
||
400 | |||
401 | /** |
||
402 | * X25519 key exchange followed by XSalsa20Poly1305 symmetric encryption |
||
403 | * |
||
404 | * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. |
||
405 | * |
||
406 | * @param string $plaintext |
||
407 | * @param string $nonce |
||
408 | * @param string $keypair |
||
409 | * @return string |
||
410 | */ |
||
411 | View Code Duplication | public static function box($plaintext, $nonce, $keypair) |
|
423 | |||
424 | /** |
||
425 | * X25519-XSalsa20-Poly1305 with one ephemeral X25519 keypair. |
||
426 | * |
||
427 | * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. |
||
428 | * |
||
429 | * @param string $message |
||
430 | * @param string $publicKey |
||
431 | * @return string |
||
432 | */ |
||
433 | View Code Duplication | public static function box_seal($message, $publicKey) |
|
467 | |||
468 | /** |
||
469 | * Opens a message encrypted via box_seal(). |
||
470 | * |
||
471 | * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. |
||
472 | * |
||
473 | * @param string $message |
||
474 | * @param string $keypair |
||
475 | * @return string |
||
476 | */ |
||
477 | View Code Duplication | public static function box_seal_open($message, $keypair) |
|
514 | |||
515 | /** |
||
516 | * Used by crypto_box() to get the crypto_secretbox() key. |
||
517 | * |
||
518 | * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. |
||
519 | * |
||
520 | * @param string $sk |
||
521 | * @param string $pk |
||
522 | * @return string |
||
523 | */ |
||
524 | public static function box_beforenm($sk, $pk) |
||
531 | |||
532 | /** |
||
533 | * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. |
||
534 | * |
||
535 | * @return string |
||
536 | */ |
||
537 | public static function box_keypair() |
||
543 | |||
544 | /** |
||
545 | * @param string $seed |
||
546 | * @return string |
||
547 | */ |
||
548 | public static function box_seed_keypair($seed) |
||
558 | |||
559 | /** |
||
560 | * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. |
||
561 | * |
||
562 | * @param string $sKey |
||
563 | * @param string $pKey |
||
564 | * @return string |
||
565 | */ |
||
566 | public static function box_keypair_from_secretkey_and_publickey($sKey, $pKey) |
||
571 | |||
572 | /** |
||
573 | * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. |
||
574 | * |
||
575 | * @param string $keypair |
||
576 | * @return string |
||
577 | * @throws RangeException |
||
578 | */ |
||
579 | View Code Duplication | public static function box_secretkey($keypair) |
|
586 | |||
587 | /** |
||
588 | * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. |
||
589 | * |
||
590 | * @param string $keypair |
||
591 | * @return string |
||
592 | * @throws RangeException |
||
593 | */ |
||
594 | View Code Duplication | public static function box_publickey($keypair) |
|
601 | |||
602 | /** |
||
603 | * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. |
||
604 | * |
||
605 | * @param string $sKey |
||
606 | * @return string |
||
607 | * @throws RangeException |
||
608 | */ |
||
609 | public static function box_publickey_from_secretkey($sKey) |
||
616 | |||
617 | /** |
||
618 | * Decrypt a message encrypted with box(). |
||
619 | * |
||
620 | * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. |
||
621 | * |
||
622 | * @param string $ciphertext |
||
623 | * @param string $nonce |
||
624 | * @param string $nonce |
||
625 | * @param string $keypair |
||
626 | * @return string |
||
627 | */ |
||
628 | public static function box_open($ciphertext, $nonce, $keypair) |
||
639 | |||
640 | /** |
||
641 | * Calculate a BLAKE2b hash. |
||
642 | * |
||
643 | * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. |
||
644 | * |
||
645 | * @param string $message |
||
646 | * @param string|null $key |
||
647 | * @param int $outlen |
||
648 | * @return string |
||
649 | * @throws RangeException |
||
650 | */ |
||
651 | View Code Duplication | public static function generichash($message, $key = '', $outlen = 32) |
|
680 | |||
681 | /** |
||
682 | * Finalize a BLAKE2b hashing context, returning the hash. |
||
683 | * |
||
684 | * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. |
||
685 | * |
||
686 | * @param string $ctx |
||
687 | * @param int $outlen |
||
688 | * @return string |
||
689 | * @throws TypeError |
||
690 | */ |
||
691 | View Code Duplication | public static function generichash_final($ctx, $outlen = 32) |
|
708 | |||
709 | /** |
||
710 | * Initialize a hashing context for BLAKE2b. |
||
711 | * |
||
712 | * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. |
||
713 | * |
||
714 | * @param string $key |
||
715 | * @param int $outputLength |
||
716 | * @return string |
||
717 | * @throws RangeException |
||
718 | */ |
||
719 | View Code Duplication | public static function generichash_init($key = '', $outputLength = 32) |
|
737 | |||
738 | /** |
||
739 | * Update a hashing context for BLAKE2b with $message |
||
740 | * |
||
741 | * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. |
||
742 | * |
||
743 | * @param string $ctx |
||
744 | * @param string $message |
||
745 | * @return string |
||
746 | */ |
||
747 | View Code Duplication | public static function generichash_update($ctx, $message) |
|
762 | |||
763 | /** |
||
764 | * Libsodium's crypto_kx(). |
||
765 | * |
||
766 | * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. |
||
767 | * |
||
768 | * @param string $my_sk |
||
769 | * @param string $their_pk |
||
770 | * @param string $client_pk |
||
771 | * @param string $server_pk |
||
772 | * @return string |
||
773 | */ |
||
774 | public static function keyExchange($my_sk, $their_pk, $client_pk, $server_pk) |
||
782 | |||
783 | /** |
||
784 | * ECDH over Curve25519 |
||
785 | * |
||
786 | * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. |
||
787 | * |
||
788 | * @param string $sKey |
||
789 | * @param string $pKey |
||
790 | * @return string |
||
791 | * |
||
792 | * @throws Error |
||
793 | */ |
||
794 | public static function scalarmult($sKey, $pKey) |
||
800 | |||
801 | /** |
||
802 | * ECDH over Curve25519, using the basepoint. |
||
803 | * Used to get a secret key from a public key. |
||
804 | * |
||
805 | * @param string $secret |
||
806 | * @return string |
||
807 | * |
||
808 | * @throws Error |
||
809 | */ |
||
810 | public static function scalarmult_base($secret) |
||
816 | |||
817 | /** |
||
818 | * This throws an Error if a zero public key was passed to the function. |
||
819 | * |
||
820 | * @param string $q |
||
821 | * @return void |
||
822 | * @throws Error |
||
823 | */ |
||
824 | View Code Duplication | protected static function scalarmult_throw_if_zero($q) |
|
836 | |||
837 | /** |
||
838 | * XSalsa20-Poly1305 authenticated symmetric-key encryption. |
||
839 | * |
||
840 | * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. |
||
841 | * |
||
842 | * @param string $plaintext |
||
843 | * @param string $nonce |
||
844 | * @param string $key |
||
845 | * @return string |
||
846 | */ |
||
847 | View Code Duplication | public static function secretbox($plaintext, $nonce, $key) |
|
909 | |||
910 | /** |
||
911 | * Decrypt a ciphertext generated via secretbox(). |
||
912 | * |
||
913 | * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. |
||
914 | * |
||
915 | * @param string $ciphertext |
||
916 | * @param string $nonce |
||
917 | * @param string $key |
||
918 | * @return string |
||
919 | * @throws Error |
||
920 | */ |
||
921 | View Code Duplication | public static function secretbox_open($ciphertext, $nonce, $key) |
|
981 | |||
982 | /** |
||
983 | * XChaCha20-Poly1305 authenticated symmetric-key encryption. |
||
984 | * |
||
985 | * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. |
||
986 | * |
||
987 | * @param string $plaintext |
||
988 | * @param string $nonce |
||
989 | * @param string $key |
||
990 | * @return string |
||
991 | */ |
||
992 | View Code Duplication | public static function secretbox_xchacha20poly1305($plaintext, $nonce, $key) |
|
1058 | |||
1059 | /** |
||
1060 | * Decrypt a ciphertext generated via secretbox_xchacha20poly1305(). |
||
1061 | * |
||
1062 | * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. |
||
1063 | * |
||
1064 | * @param string $ciphertext |
||
1065 | * @param string $nonce |
||
1066 | * @param string $key |
||
1067 | * @return string |
||
1068 | * @throws Error |
||
1069 | */ |
||
1070 | View Code Duplication | public static function secretbox_xchacha20poly1305_open($ciphertext, $nonce, $key) |
|
1132 | |||
1133 | /** |
||
1134 | * Detached Ed25519 signature. |
||
1135 | * |
||
1136 | * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. |
||
1137 | * |
||
1138 | * @param string $message |
||
1139 | * @param string $sk |
||
1140 | * @return string |
||
1141 | */ |
||
1142 | public static function sign_detached($message, $sk) |
||
1146 | |||
1147 | /** |
||
1148 | * Attached Ed25519 signature. (Returns a signed message.) |
||
1149 | * |
||
1150 | * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. |
||
1151 | * |
||
1152 | * @param string $message |
||
1153 | * @param string $sk |
||
1154 | * @return string |
||
1155 | */ |
||
1156 | public static function sign($message, $sk) |
||
1160 | |||
1161 | /** |
||
1162 | * Opens a signed message. If valid, returns the message. |
||
1163 | * |
||
1164 | * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. |
||
1165 | * |
||
1166 | * @param string $signedMessage |
||
1167 | * @param string $pk |
||
1168 | * @return string |
||
1169 | */ |
||
1170 | public static function sign_open($signedMessage, $pk) |
||
1174 | |||
1175 | /** |
||
1176 | * Verify a detached signature of a given message and public key. |
||
1177 | * |
||
1178 | * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. |
||
1179 | * |
||
1180 | * @param string $signature |
||
1181 | * @param string $message |
||
1182 | * @param string $pk |
||
1183 | * @return bool |
||
1184 | */ |
||
1185 | public static function sign_verify_detached($signature, $message, $pk) |
||
1189 | } |
||
1190 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.