def load(self): keyfdir = "%s/sk/.%s" % (self.basedir, self.me) if not os.path.exists(keyfdir): os.mkdir(keyfdir) return self keyfname = '%s/%s' % (keyfdir, self.peer) if not os.path.exists(keyfname): return self if not self.me_id: self.me_id = publickey.Identity(self.me, basedir=self.basedir) with open(keyfname, 'rb') as fd: nonce = fd.read(nacl.crypto_box_NONCEBYTES) plain = nacl.crypto_box_open(fd.read(), nonce, self.me_id.cp, self.me_id.cs) c = nacl.crypto_scalarmult_curve25519_BYTES i = 0 self.e_in = plain[:c] i += c self.e_out = plain[i:i + c] i += c self.peer_pub = plain[i:i + c] i += c c = nacl.crypto_secretbox_KEYBYTES self.out_k = plain[i:i + c] i += c self.in_k = plain[i:i + c] i += c self.in_prev = plain[i:i + c]
def test_crypto_box_open(self): m = b"howdy" pk, sk = pysodium.crypto_box_keypair() n = pysodium.randombytes(pysodium.crypto_box_NONCEBYTES) c = pysodium.crypto_box(m, n, pk, sk) plaintext = pysodium.crypto_box_open(c, n, pk, sk) self.assertEqual(m, plaintext)
def load(self): keyfdir="%s/sk/.%s" % (self.basedir, self.me) if not os.path.exists(keyfdir): os.mkdir(keyfdir) return self keyfname='%s/%s' % (keyfdir, self.peer) if not os.path.exists(keyfname): return self if not self.me_id: self.me_id = publickey.Identity(self.me, basedir=self.basedir) with open(keyfname,'rb') as fd: nonce = fd.read(nacl.crypto_box_NONCEBYTES) plain = nacl.crypto_box_open(fd.read(), nonce, self.me_id.cp, self.me_id.cs) c=nacl.crypto_scalarmult_curve25519_BYTES i=0 self.e_in = plain[:c] i+=c self.e_out = plain[i:i+c] i+=c self.peer_pub = plain[i:i+c] i+=c c=nacl.crypto_secretbox_KEYBYTES self.out_k = plain[i:i+c] i+=c self.in_k = plain[i:i+c] i+=c self.in_prev = plain[i:i+c]
def test_AsymCrypto_With_Seeded_Keypair(self): msg = b"correct horse battery staple" nonce = pysodium.randombytes(pysodium.crypto_box_NONCEBYTES) pk, sk = pysodium.crypto_box_seed_keypair("howdy") c = pysodium.crypto_box(msg, nonce, pk, sk) m = pysodium.crypto_box_open(c, nonce, pk, sk) self.assertEqual(msg, m)
def keydecrypt(self, peers): for nonce, ck in peers: for keys in get_public_keys(basedir=self.basedir): try: key = nacl.crypto_box_open(ck, nonce, keys.cp, self.cs) except ValueError: continue return (keys.name, key) return None, None
def load(self): keyfname="%s/dh/%s/%s" % (self.basedir, self.me, self.id) if not self.me_id: self.me_id = publickey.Identity(self.me, basedir=self.basedir) with open(keyfname,'r') as fd: nonce = fd.read(nacl.crypto_box_NONCEBYTES) raw = fd.read() self.key = nacl.crypto_box_open(raw, nonce, self.me_id.cp, self.me_id.cs) os.remove(keyfname)
def locate_pack_recipient_key(recipients: Sequence[dict], my_verkey: bytes, my_sigkey: bytes) -> (bytes, str, str): """ Locate pack recipient key. Decode the encryption key and sender verification key from a corresponding recipient block, if any is defined. Args: recipients: Recipients to locate find_key: Function used to find private key Returns: A tuple of (cek, sender_vk, recip_vk_b58) Raises: ValueError: If no corresponding recipient key found """ not_found = [] for recip in recipients: if not recip or "header" not in recip or "encrypted_key" not in recip: raise ValueError("Invalid recipient header") recip_vk_b58 = recip["header"].get("kid") if bytes_to_b58(my_verkey) != recip_vk_b58: not_found.append(recip_vk_b58) continue recip_vk = b58_to_bytes(recip_vk_b58) pk = pysodium.crypto_sign_pk_to_box_pk(my_verkey) sk = pysodium.crypto_sign_sk_to_box_sk(my_sigkey) encrypted_key = b64_to_bytes(recip["encrypted_key"], urlsafe=True) nonce_b64 = recip["header"].get("iv") nonce = b64_to_bytes(nonce_b64, urlsafe=True) if nonce_b64 else None sender_b64 = recip["header"].get("sender") enc_sender = b64_to_bytes(sender_b64, urlsafe=True) if sender_b64 else None if nonce and enc_sender: sender_vk_bin = pysodium.crypto_box_seal_open(enc_sender, pk, sk) sender_vk = sender_vk_bin.decode("ascii") sender_pk = pysodium.crypto_sign_pk_to_box_pk( b58_to_bytes(sender_vk_bin)) cek = pysodium.crypto_box_open(encrypted_key, nonce, sender_pk, sk) else: sender_vk = None cek = pysodium.crypto_box_seal_open(encrypted_key, pk, sk) return cek, sender_vk, recip_vk_b58 raise ValueError( "No corresponding recipient key found in {}".format(not_found))
def decrypt(self, cipher, nonce): if self.in_k == (b'\0' * nacl.crypto_scalarmult_curve25519_BYTES): # use pk crypto to decrypt the packet return nacl.crypto_box_open(cipher, nonce, self.peer_id.cp, self.me_id.cs) else: # decrypt using chained keys try: return nacl.crypto_secretbox_open(cipher, nonce, self.in_k) except ValueError: # with previous key in case a prev send failed to be delivered return nacl.crypto_secretbox_open(cipher, nonce, self.in_prev)
def handle(self): data = self.request[0] nonce = data[:pysodium.crypto_box_NONCEBYTES] if nonce in nonces: return box = data[pysodium.crypto_box_NONCEBYTES:] validity, payload = cbor.loads( pysodium.crypto_box_open(box, nonce, ap, sk)) if validity < time(): return nonces[nonce] = validity cw.signal.emit(payload)
def decryptSalsaSession(self, proposeTuple, myEncrypKey): cp = 0 nonce = proposeTuple['K'][cp:cp + 24] cp += 24 cipherText = proposeTuple['K'][cp:] # encrypSession = pysodium.crypto_box(cipherText, nonce, servPubkey, myEncrypKey) try: salsaSession = pysodium.crypto_box_open(cipherText, nonce, proposeTuple['C']['K_E'], myEncrypKey) except: salsaSession = None return salsaSession
def test_box(): m = b"passwd" pk, sk = pysodium.crypto_box_keypair() n = pysodium.randombytes(pysodium.crypto_box_NONCEBYTES) print(n) c = pysodium.crypto_box(m, n, pk, sk) plaintext = pysodium.crypto_box_open(c, n, pk, sk) print(plaintext)
def decrypt_body(self, msg, nonce_s, public_key, secret_key): try: body_s = pysodium.crypto_box_open(msg, nonce_s, public_key, secret_key) if not body_s or (len(body_s) < 8): return None (seq_s, body_s) = self.next_chunk(body_s, 4) (ack_s, body_s) = self.next_chunk(body_s, 4) seq_n = self.bytes_int(seq_s) ack_n = self.bytes_int(ack_s) self.log_info('GOT seq ' + str(seq_n) + " ack " + str(ack_n)) self.log_info(repr(body_s)) return (seq_n, ack_n, body_s) except ValueError: return None
def decode_message(self, response: dict) -> (dict): """Decode response message. Also verifies the received/expected nonce.""" try: nonce = decode(response["nonce"]) msg_response = decode(response["message"]) msg_response = pysodium.crypto_box_open( msg_response, nonce, self.server_key, self.get_private_key()).decode() msg_response = json.loads(msg_response) logging.debug("Response message: " + str(msg_response)) verify_expected_nonce(self.nonce, nonce) self.nonce = get_nonce(nonce) except KeyError as e: logging.warning("Invalid response: " + str(response)) msg_response = {} return msg_response
def auth_decrypt_message(enc_message: bytes, my_verkey: bytes, my_sigkey: bytes) -> (bytes, str): """ Apply auth_decrypt to a binary message. Args: enc_message: The encrypted message secret: Secret for signing keys Returns: A tuple of (decrypted message, sender verkey) """ pk = pysodium.crypto_sign_pk_to_box_pk(my_verkey) sk = pysodium.crypto_sign_sk_to_box_sk(my_sigkey) body = pysodium.crypto_box_seal_open(enc_message, pk, sk) unpacked = msgpack.unpackb(body, raw=False) sender_vk = unpacked["sender"] nonce = b64_to_bytes(unpacked["nonce"]) enc_message = b64_to_bytes(unpacked["msg"]) sender_pk = pysodium.crypto_sign_pk_to_box_pk(b58_to_bytes(sender_vk)) message = pysodium.crypto_box_open(enc_message, nonce, sender_pk, sk) return message, sender_vk
def decrypt_handler(infile=None, outfile=None, self=None, peer=None, max_recipients=20, basedir=None): # provides a high level function to do decryption of files # infile specifies the filename of the input file, # if '-' or not specified it uses stdin # outfile specifies the filename of the output file, if not specified # it uses the same filename with '.pbp' appended # self specifies the recipient of the message for using pk crypto # basedir provides a root for the keystores needed for pk crypto # if self is specified pk crypto is used, otherwise symmetric # this function also handles buffering. fd = inputfd(infile) outfd = outputfd(outfile) key = None # asym if self: me = publickey.Identity(self, basedir=basedir) if peer: peer = publickey.Identity(peer, basedir=basedir, publicOnly=True) sender = None size = None i = 0 while i < (max_recipients if not size else size): i += 1 rnonce = fd.read(nacl.crypto_box_NONCEBYTES) ct = fd.read(nacl.crypto_secretbox_KEYBYTES + 2 + nacl.crypto_secretbox_MACBYTES) if sender: continue for keys in ([peer] if peer else publickey.get_public_keys( basedir=basedir)): try: tmp = nacl.crypto_box_open(ct, rnonce, keys.cp, me.cs) except ValueError: continue key = tmp[:nacl.crypto_secretbox_KEYBYTES] size = struct.unpack('>H', tmp[nacl.crypto_secretbox_KEYBYTES:])[0] sender = keys.name break me.clear() if not sender: raise ValueError('decryption failed') # sym else: pwd = getpass.getpass('Passphrase for decrypting: ') key = scrypt.hash(pwd, scrypt_salt)[:nacl.crypto_secretbox_KEYBYTES] sender = None clearmem(pwd) pwd = None if key: nonce = fd.read(nacl.crypto_secretbox_NONCEBYTES) buf = fd.read(BLOCK_SIZE + nacl.crypto_secretbox_MACBYTES) while buf: outfd.write(decrypt((nonce, buf), k=key)) nonce = inc_nonce(nonce) buf = fd.read(BLOCK_SIZE + nacl.crypto_secretbox_MACBYTES) clearmem(key) key = None if fd != sys.stdin: fd.close() if outfd != sys.stdout and type(outfd) == file: outfd.close() return sender
def test_crypto_box_open(self): pk, sk = pysodium.crypto_box_keypair() n = pysodium.randombytes(pysodium.crypto_box_NONCEBYTES) c = pysodium.crypto_box(b"howdy", n, pk, sk) pysodium.crypto_box_open(c, n, pk, sk)
def DecryptPacket(packet, pk, sk): nounce = packet[:24] data = packet[24:] LAST_NOUNCE = nounce return pysodium.crypto_box_open(data, nounce, pk, sk)
def decrypt(message, nonce, serverKey, secretKey): return pysodium.crypto_box_open(message, nonce, serverKey, secretKey)
def decrypt_handler(infile=None, outfile=None, self=None, peer=None, max_recipients = 20, basedir=None): # provides a high level function to do decryption of files # infile specifies the filename of the input file, # if '-' or not specified it uses stdin # outfile specifies the filename of the output file, if not specified # it uses the same filename with '.pbp' appended # self specifies the recipient of the message for using pk crypto # basedir provides a root for the keystores needed for pk crypto # if self is specified pk crypto is used, otherwise symmetric # this function also handles buffering. fd = inputfd(infile) outfd = outputfd(outfile) key = None # asym if self: me = publickey.Identity(self, basedir=basedir) if peer: peer = publickey.Identity(peer, basedir=basedir, publicOnly=True) sender = None size = None i=0 while i < (max_recipients if not size else size): i+=1 rnonce = fd.read(nacl.crypto_box_NONCEBYTES) ct = fd.read(nacl.crypto_secretbox_KEYBYTES+2+nacl.crypto_secretbox_MACBYTES) if sender: continue for keys in ([peer] if peer else publickey.get_public_keys(basedir=basedir)): try: tmp = nacl.crypto_box_open(ct, rnonce, keys.cp, me.cs) except ValueError: continue key = tmp[:nacl.crypto_secretbox_KEYBYTES] size = struct.unpack('>H',tmp[nacl.crypto_secretbox_KEYBYTES:])[0] sender = keys.name break me.clear() if not sender: raise ValueError('decryption failed') # sym else: pwd = getpass.getpass('Passphrase for decrypting: ') key = scrypt.hash(pwd, scrypt_salt)[:nacl.crypto_secretbox_KEYBYTES] sender = None clearmem(pwd) pwd=None if key: nonce = fd.read(nacl.crypto_secretbox_NONCEBYTES) buf = fd.read(BLOCK_SIZE + nacl.crypto_secretbox_MACBYTES) while buf: outfd.write(decrypt((nonce, buf), k = key)) nonce = inc_nonce(nonce) buf = fd.read(BLOCK_SIZE + nacl.crypto_secretbox_MACBYTES) clearmem(key) key = None if fd != sys.stdin: fd.close() if outfd != sys.stdout: outfd.close() return sender
def decrypt_message(public_key, secret_key, message): decrypted = pysodium.crypto_box_open(message[40:], message[0:24], public_key, secret_key) return decrypted
def decrypt(ecryptedMessage, nonce, private_key, pub_key): new_private_key = pysodium.crypto_sign_sk_to_box_sk(private_key) new_pub_key = pysodium.crypto_sign_pk_to_box_pk(pub_key) return pysodium.crypto_box_open(b64decode(ecryptedMessage), b64decode(nonce), new_pub_key, new_private_key).decode("utf-8")
def test_pysodium(): """ Test all the functions needed from pysodium libarary (libsodium) """ # crypto_sign signatures with Ed25519 keys # create keypair without seed verkey, sigkey = pysodium.crypto_sign_keypair() assert len(verkey) == 32 == pysodium.crypto_sign_PUBLICKEYBYTES assert len(sigkey) == 64 == pysodium.crypto_sign_SECRETKEYBYTES assert 32 == pysodium.crypto_sign_SEEDBYTES sigseed = pysodium.randombytes(pysodium.crypto_sign_SEEDBYTES) assert len(sigseed) == 32 # seed = (b'J\xeb\x06\xf2BA\xd6/T\xe1\xe2\xe2\x838\x8a\x99L\xd9\xb5(\\I\xccRb\xc8\xd5\xc7Y\x1b\xb6\xf0') # Ann's seed sigseed = ( b'PTi\x15\xd5\xd3`\xf1u\x15}^r\x9bfH\x02l\xc6\x1b\x1d\x1c\x0b9\xd7{\xc0_\xf2K\x93`' ) assert len(sigseed) == 32 # try key stretching from 16 bytes using pysodium.crypto_pwhash() assert 16 == pysodium.crypto_pwhash_SALTBYTES salt = pysodium.randombytes(pysodium.crypto_pwhash_SALTBYTES) assert len(salt) == 16 # salt = b'\x19?\xfa\xc7\x8f\x8b\x7f\x8b\xdbS"$\xd7[\x85\x87' # algorithm default is argon2id sigseed = pysodium.crypto_pwhash( outlen=32, passwd="", salt=salt, opslimit=pysodium.crypto_pwhash_OPSLIMIT_INTERACTIVE, memlimit=pysodium.crypto_pwhash_MEMLIMIT_INTERACTIVE, alg=pysodium.crypto_pwhash_ALG_DEFAULT) assert len(sigseed) == 32 # seed = (b'\xa9p\x89\x7f+\x0e\xc4\x9c\xf2\x01r\xafTI\xc0\xfa\xac\xd5\x99\xf8O\x8f=\x843\xa2\xb6e\x9fO\xff\xd0') # creates signing/verification key pair from seed verkey, sigkey = pysodium.crypto_sign_seed_keypair(sigseed) assert len(verkey) == 32 assert len(sigkey) == 64 # sigkey is seed and verkey concatenated. Libsodium does this as an optimization # because the signing scheme needs both the private key (seed) and the public key so # instead of recomputing the public key each time from the secret key it requires # the public key as an input of and instead of two separate inputs, one for the # secret key and one for the public key, it uses a concatenated form. # Essentially crypto_sign_seed_keypair and crypto_sign_keypair return redundant # information in the duple (verkey, sigkey) because sigkey includes verkey # so one could just store sigkey and extract verkey or sigseed when needed # or one could just store verkey and sigseed and reconstruct sigkey when needed. # crypto_sign_detached requires sigkey (sigseed + verkey) # crypto_sign_verify_detached reqires verkey only # https://crypto.stackexchange.com/questions/54353/why-are-nacl-secret-keys-64-bytes-for-signing-but-32-bytes-for-box assert sigseed == sigkey[:32] assert verkey == sigkey[32:] assert sigkey == sigseed + verkey # vk = (b'B\xdd\xbb}8V\xa0\xd6lk\xcf\x15\xad9\x1e\xa7\xa1\xfe\xe0p<\xb6\xbex\xb0s\x8d\xd6\xf5\xa5\xe8Q') # utility function to extract seed from secret sigkey (really just extracting from front half) assert sigseed == pysodium.crypto_sign_sk_to_seed(sigkey) assert 64 == pysodium.crypto_sign_BYTES msg = "The lazy dog jumped over the river" msgb = msg.encode( "utf-8") # must convert unicode string to bytes in order to sign it assert msgb == b'The lazy dog jumped over the river' sig = pysodium.crypto_sign_detached(msgb, sigseed + verkey) # sigkey = seed + verkey assert len(sig) == 64 """ sig = (b"\x99\xd2<9$$0\x9fk\xfb\x18\xa0\x8c@r\x122.k\xb2\xc7\x1fp\x0e'm\x8f@" b'\xaa\xa5\x8c\xc8n\x85\xc8!\xf6q\x91p\xa9\xec\xcf\x92\xaf)\xde\xca' b'\xfc\x7f~\xd7o|\x17\x82\x1d\xd4<o"\x81&\t') """ #siga = pysodium.crypto_sign(msg.encode("utf-8"), sk)[:pysodium.crypto_sign_BYTES] #assert len(siga) == 64 #assert sig == siga try: # verify returns None if valid else raises ValueError result = pysodium.crypto_sign_verify_detached(sig, msgb, verkey) except Exception as ex: assert False assert not result assert result is None sigbad = sig[:-1] sigbad += b'A' try: # verify returns None if valid else raises ValueError result = pysodium.crypto_sign_verify_detached(sigbad, msgb, verkey) except Exception as ex: assert True assert isinstance(ex, ValueError) # crypto_box authentication encryption with X25519 keys apubkey, aprikey = pysodium.crypto_box_keypair() assert len(apubkey) == 32 == pysodium.crypto_box_SECRETKEYBYTES assert len(aprikey) == 32 == pysodium.crypto_box_PUBLICKEYBYTES repubkey = pysodium.crypto_scalarmult_curve25519_base(aprikey) assert repubkey == apubkey assert 32 == pysodium.crypto_box_SEEDBYTES boxseed = pysodium.randombytes(pysodium.crypto_box_SEEDBYTES) assert len(boxseed) == 32 bpubkey, bprikey = pysodium.crypto_box_seed_keypair(boxseed) assert len(bpubkey) == 32 assert len(bprikey) == 32 repubkey = pysodium.crypto_scalarmult_curve25519_base(bprikey) assert repubkey == bpubkey assert 24 == pysodium.crypto_box_NONCEBYTES nonce = pysodium.randombytes(pysodium.crypto_box_NONCEBYTES) assert len(nonce) == 24 # nonce = b'\x11\xfbi<\xf2\xb6k\xa05\x0c\xf9\x86t\x07\x8e\xab\x8a\x97nG\xe8\x87,\x94' atob_tx = "Hi Bob I'm Alice" atob_txb = atob_tx.encode("utf-8") # Detached recomputes shared key every time. # A encrypt to B acrypt, amac = pysodium.crypto_box_detached(atob_txb, nonce, bpubkey, aprikey) amacl = pysodium.crypto_box_MACBYTES assert amacl == 16 # amac = b'\xa1]\xc6ML\xe2\xa9:\xc0\xdc\xab\xa5\xc4\xc7\xf4\xdb' # acrypt = (b'D\n\x17\xb6z\xd8+t)\xcc`y\x1d\x10\x0cTC\x02\xb5@\xe2\xf2\xc9-(\xec*O\xb8~\xe2\x1a\xebO') # when transmitting prepend amac to crypt acipher = pysodium.crypto_box(atob_txb, nonce, bpubkey, aprikey) assert acipher == amac + acrypt atob_rxb = pysodium.crypto_box_open_detached(acrypt, amac, nonce, apubkey, bprikey) atob_rx = atob_rxb.decode("utf-8") assert atob_rx == atob_tx assert atob_rxb == atob_txb atob_rxb = pysodium.crypto_box_open(acipher, nonce, apubkey, bprikey) atob_rx = atob_rxb.decode("utf-8") assert atob_rx == atob_tx assert atob_rxb == atob_txb btoa_tx = "Hello Alice I am Bob" btoa_txb = btoa_tx.encode("utf-8") # B encrypt to A bcrypt, bmac = pysodium.crypto_box_detached(btoa_txb, nonce, apubkey, bprikey) # bmac = b'\x90\xe07=\xd22\x8fh2\xff\xdd\x84tC\x053' # bcrypt = (b'8\xb5\xba\xe7\xcc\xae B\xefx\xe6{U\xf7\xefA\x00\xc7|\xdbu\xcfc\x01$\xa9\xa2P\xa7\x84\xa5\xae\x180') # when transmitting prepend amac to crypt bcipher = pysodium.crypto_box(btoa_txb, nonce, apubkey, bprikey) assert bcipher == bmac + bcrypt btoa_rxb = pysodium.crypto_box_open_detached(bcrypt, bmac, nonce, bpubkey, aprikey) btoa_rx = btoa_rxb.decode("utf-8") assert btoa_rx == btoa_tx assert btoa_rxb == btoa_txb btoa_rxb = pysodium.crypto_box_open(bcipher, nonce, bpubkey, aprikey) btoa_rx = btoa_rxb.decode("utf-8") assert btoa_rx == btoa_tx assert btoa_rxb == btoa_txb # compute shared key asymkey = pysodium.crypto_box_beforenm(bpubkey, aprikey) bsymkey = pysodium.crypto_box_beforenm(apubkey, bprikey) assert asymkey == bsymkey acipher = pysodium.crypto_box_afternm(atob_txb, nonce, asymkey) atob_rxb = pysodium.crypto_box_open_afternm(acipher, nonce, bsymkey) assert atob_rxb == atob_txb bcipher = pysodium.crypto_box_afternm(btoa_txb, nonce, bsymkey) btoa_rxb = pysodium.crypto_box_open_afternm(bcipher, nonce, asymkey) assert btoa_rxb == btoa_txb # crypto_box_seal public key encryption with X25519 keys # uses same X25519 type of keys as crypto_box authenticated encryption # so when converting sign key Ed25519 to X25519 can use for both types of encryption pubkey, prikey = pysodium.crypto_box_keypair() assert len(pubkey) == 32 == pysodium.crypto_box_PUBLICKEYBYTES assert len(prikey) == 32 == pysodium.crypto_box_SECRETKEYBYTES assert 48 == pysodium.crypto_box_SEALBYTES msg_txb = "Catch me if you can.".encode("utf-8") assert msg_txb == b'Catch me if you can.' cipher = pysodium.crypto_box_seal(msg_txb, pubkey) assert len(cipher) == 48 + len(msg_txb) msg_rxb = pysodium.crypto_box_seal_open(cipher, pubkey, prikey) assert msg_rxb == msg_txb # convert Ed25519 key pair to X25519 key pair # https://blog.filippo.io/using-ed25519-keys-for-encryption/ # https://libsodium.gitbook.io/doc/advanced/ed25519-curve25519 # crypto_sign_ed25519_pk_to_curve25519 # crypto_sign_ed25519_sk_to_curve25519 pubkey = pysodium.crypto_sign_pk_to_box_pk(verkey) assert len(pubkey) == pysodium.crypto_box_PUBLICKEYBYTES prikey = pysodium.crypto_sign_sk_to_box_sk(sigkey) assert len(prikey) == pysodium.crypto_box_SECRETKEYBYTES repubkey = pysodium.crypto_scalarmult_curve25519_base(prikey) assert repubkey == pubkey msg_txb = "Encoded using X25519 key converted from Ed25519 key".encode( "utf-8") cipher = pysodium.crypto_box_seal(msg_txb, pubkey) assert len(cipher) == 48 + len(msg_txb) msg_rxb = pysodium.crypto_box_seal_open(cipher, pubkey, prikey) assert msg_rxb == msg_txb """
def __decrypt(msg, nonce, serverKey, secretKey): dec = pysodium.crypto_box_open(base64.b64decode(msg), base64.b64decode(nonce), base64.b64decode(serverKey), base64.b64decode(secretKey)) return dec
def oneshotDecrypt(sk, pk, data): n = data[:pysodium.crypto_box_NONCEBYTES] c = data[len(n):] return pysodium.crypto_box_open(c, n, pk, sk)