Package: psypher
Psypher - A modern asymmetric encryption scheme.Psypher is a modern cryptography module providing high-level security recipes with simple interfaces. It is built for securing communication through insecure  channels.InstallationThis module is available via PyPI:$pipinstallpsypherIf you want to use the source code directly, make sure you install thecryptographydependency.$pipinstallcryptographyBasic UsageAll the interface Psypher provides is accessible through theSchemeinterface. Use thedefaultstatic method to obtain an instance of the default scheme (curve25519-chacha20poly1305).>>>frompsypherimportScheme>>>s1,s2=Scheme.default(),Scheme.default()>>>s1.__class__.__name__'Curve25519ChaCha20Poly1305Scheme'The private and public key is accessible with theprivateKeyandpublicKeyproperties. The basic usage of these keys are shown below.# key export (also suitable for public keys)key1=s1.privateKey.export()# byteskey2=s2.privateKey.exportJson()# str# key import (also suitable for public keys)psypher.secret.Curve25519PrivateKey.importKey(key1)psypher.secret.Curve25519PrivateKey.importJson(key2)# encrypted key export (private keys only)key1=s1.privateKey.secureExport(b'password')key2=s2.privateKey.secureExportJson(b'password')# encrypted key import (private keys only)psypher.secret.Curve25519PrivateKey.importKey(key1,b'password')psypher.secret.Curve25519PrivateKey.importJson(key2,b'password')# key fingerprint (public keys only)print(s1.publicKey.digest)When using encrypted key export, the default behaviours is to derive the wrapping key from the password usingPBKDF2. However, you can specifyderive=Falseto disable this kind of behaviour and to use your material as key directly.IPublicKey.digestis a cached property, so it might not behave as you expect it to be. See theAdvanced Usage / Cache Modeto learn more.Theexport,exportJsonmethods is also defined on the scheme as a shortcut to the public key. Use thereceiveandreceiveJsonmethods to receive remote key from peers:>>>s1.receive(s2.export())>>>s2.receiveJson(s1.exportJson())Use theshareSecretproperty to calculate the negotiated shared secret. This property is CACHED, that means it only evaluates once. For detailed information about caching, please navigate to theAdvanced Usage / Cache Modesection.>>>s1.sharedSecret==s2.sharedSecretTrueTo generate the digital signature of specific message, use thesignmethod. Callverifyon the other side to verify the message. You can only verify messages signed by your peer. The signature generated is deterministic.>>>data=b'My telephone number is 123456!'>>>signature=s1.sign(data)>>>s2.verify(data,signature)True>>>s2.verify(b'My telephone number is 654321!',signature)FalseIf you just want to check the integrity of your message therefore don't require such cryptographical strength of your signature, or if you need a shorter signature value, theintegritySignmethod may suits you. It uses HMAC to sign the message, producing only 32 bytes output. Likewise, theintegrityVerifymethod can be used to verify this signature:>>>data=b'My telephone number is 123456!'>>>signature=s1.integritySign(data)>>>s2.integrityVerify(data,signature)True>>>s2.integrityVerify(b'My telephone number is 654321!',signature)FalseTo encrypt your message, use theencryptmethod. Calldecrypton the other side to decrypt your message. You can only decrypt messages encrypted by your peer. The ciphertext is different each time you callencrypt, even if you are encrypting the same message.>>>data=b'The darkest secret lies here.'>>>ciphertext=s2.encrypt(data)>>>s1.decrypt(ciphertext)==dataTrue>>>frompsypher.errorsimportInvalidCiphertext>>>try:...s1.decrypt(b'This is absolutely illegal')...exceptInvalidCiphertext:...passAdvanced UsageBelow are some complicated usages of this module beyond the normal usage.Cache ModeThe cache mode is enabled by default, which means certain methods or property will only be calculated once and cached. Cached items includesIPublicKey.digestand<KeyPairClass>.sharedSecret. You can disable caching globally with the following statements:>>>frompsypherimportcache>>>cache.setenabled(False)You can access the cache object through the unbound version of the method or property. Here are some usages:# queryfrompsypher.secretimportIPublicKeyIPublicKey.digest.fget.enabled# partially disableIPublicKey.digest.fget.enabled=FalseEccKeyPair.sharedSecret.fget.enabled=False# clear cache for all instancesCurve25519KeyPair.sharedSecret.fget.clearCache()If you disabled the cache globally, theenabledproperty will returnFalseon every instance, even if you set it toTrue.Customize SchemeThe scheme object is located in thepsypher.ciphermodule. A scheme is consisted of two parts - the key pair and the symmetric encryptor. You could customize these parts.The module provides two built-in schemes:Curve15519ChaCha20Poly1305Scheme, which is the default, andSecp256k1AesGcmScheme, which is recommended to use in commercial circumstances. These schemes produces the ciphertext with similar structure:Curve25519ChaCha20Poly1305Input: plain text (X bytes)Output:EphKeyHkdfSaltAeadNonceCiphertextAeadTagTotal32 bytes16 bytes12 bytesX bytes16 bytes76+X bytesSecp256k1AesGcm:Input: plain text (X bytes)Output:EphKeyHkdfSaltAeadNonceCiphertextAeadTagTotal65 bytes16 bytes12 bytesX bytes16 bytes109+X bytesThese schemes can be found in thepsypher.schememodule:>>>frompsypher.schemeimportSecp256k1AesGcmScheme>>>s1=Secp256k1AesGcmScheme.generate()You can also customize the schemes:>>>frompsypher.cipherimportAesGcmEncryptor>>>frompsypher.secretimportCurve25519KeyPair>>>frompsypher.schemeimportScheme>>>s1=Scheme(Curve25519KeyPair.generate(),AesGcmEncryptor)To fully build your own customized scheme, you may want to inherit from theIKeyPairclass. You must implement theIPrivateKeyandIPublicKeyinterfaces too. TheIEncryptorinterface however, is a static interface, only containing static methods. For more details, please see the source code.Support & LicenseThis module is built on thepyca/cryptographylibrary. Seetheir Github Repository.This software is licensed under theMIT License. For more information, see theLicense Text.