pyca / pynacl Goto Github PK
View Code? Open in Web Editor NEWPython binding to the Networking and Cryptography (NaCl) library
Home Page: https://pynacl.readthedocs.io/
License: Apache License 2.0
Python binding to the Networking and Cryptography (NaCl) library
Home Page: https://pynacl.readthedocs.io/
License: Apache License 2.0
Hi,
Thanks for the awesome library. This is not a bug report so much as an assistance request.
When I sign a message as per the doc, the "signed" result is a string, both:
isinstance(signed, str)
and
isinstance(signed, nacl.signing.SignedMessage)
return true.
However I can't seem to encode the signed message like I can with all of the other provided objects.
When I attempt:
In [1]: import nacl.utils
In [2]: import nacl.signing
In [3]: signing_key = nacl.signing.SigningKey.generate()
In [4]: signed = signing_key.sign(b"abc123")
In [5]: signed.encode(encoder = nacl.encoding.HexEncoder)
I get the following error:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-5-c597ca2a169e> in <module>()
----> 1 signed.encode(encoder = nacl.encoding.HexEncoder)
TypeError: 'encoder' is an invalid keyword argument for this function
So I used base64.b64encode to encode the signed message for transport, however once decoded on the other side I no longer have access to the "signed.signature" and "signed.message" attributes.
In [11]: signed.message
Out[11]: 'abc123'
In [12]: encoded = base64.b64encode(signed)
In [13]: decoded = base64.b64decode(encoded)
In [14]: encoded.message
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-14-68a604c6014b> in <module>()
----> 1 encoded.message
AttributeError: 'str' object has no attribute 'message'
Do I have to parse the signed message myself?
Is there any way to cast the signed str back to nacl.signing.SignedMessage to programmatically retrieve signed.message?
I've got a big dump here. I may be interpreting this incorrectly, but it appears that there is a problem "verifying" sodium, at line 77 of nacl.py. At first the problem occurred on my primary machine, but I fired up a clean Xubuntu sandbox and got the same issues.
In both experiments I am also a common factor, which is where I suspect the real issue is, but just in case, I'll try to be as detailed as possible about replicating it so the report is helpful. I'm going to keep trying stuff and report back.
Python version: 2.7.3
GCC Version: 4.7.2
libsodium version: 0.3 (static and dynamic/shared)
OS: 64bit Xubuntu
payton@sidony:~/Documents/pynacl-master$ python setup.py test
/usr/bin/ld: /usr/local/lib/libsodium.a(libsodium_la-base.o): relocation R_X86_64_PC32 against symbol `base' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Bad value
collect2: error: ld returned 1 exit status
Traceback (most recent call last):
File "setup.py", line 10, in <module>
import nacl.nacl
File "/home/payton/Documents/pynacl-master/nacl/nacl.py", line 77, in <module>
lib = ffi.verify("#include <sodium.h>", libraries=["sodium"])
File "/usr/local/lib/python2.7/dist-packages/cffi-0.5-py2.7-linux-x86_64.egg/cffi/api.py", line 305, in verify
lib = self.verifier.load_library()
File "/usr/local/lib/python2.7/dist-packages/cffi-0.5-py2.7-linux-x86_64.egg/cffi/verifier.py", line 68, in load_library
self.compile_module()
File "/usr/local/lib/python2.7/dist-packages/cffi-0.5-py2.7-linux-x86_64.egg/cffi/verifier.py", line 56, in compile_module
self._compile_module()
File "/usr/local/lib/python2.7/dist-packages/cffi-0.5-py2.7-linux-x86_64.egg/cffi/verifier.py", line 137, in _compile_module
outputfilename = ffiplatform.compile(tmpdir, self.get_extension())
File "/usr/local/lib/python2.7/dist-packages/cffi-0.5-py2.7-linux-x86_64.egg/cffi/ffiplatform.py", line 25, in compile
outputfilename = _build(tmpdir, ext)
File "/usr/local/lib/python2.7/dist-packages/cffi-0.5-py2.7-linux-x86_64.egg/cffi/ffiplatform.py", line 50, in _build
raise VerificationError('%s: %s' % (e.__class__.__name__, e))
cffi.ffiplatform.VerificationError: LinkError: command 'gcc' failed with exit status 1
payton@sidony:~/Documents/pynacl-master$ python setup.py test
Traceback (most recent call last):
File "setup.py", line 10, in <module>
import nacl.nacl
File "/home/payton/Documents/pynacl-master/nacl/nacl.py", line 77, in <module>
lib = ffi.verify("#include <sodium.h>", libraries=["sodium"])
File "/usr/local/lib/python2.7/dist-packages/cffi-0.5-py2.7-linux-x86_64.egg/cffi/api.py", line 305, in verify
lib = self.verifier.load_library()
File "/usr/local/lib/python2.7/dist-packages/cffi-0.5-py2.7-linux-x86_64.egg/cffi/verifier.py", line 69, in load_library
return self._load_library()
File "/usr/local/lib/python2.7/dist-packages/cffi-0.5-py2.7-linux-x86_64.egg/cffi/verifier.py", line 149, in _load_library
return self._vengine.load_library()
File "/usr/local/lib/python2.7/dist-packages/cffi-0.5-py2.7-linux-x86_64.egg/cffi/vengine_cpy.py", line 123, in load_library
raise ffiplatform.VerificationError(error)
cffi.ffiplatform.VerificationError: importing '/home/payton/Documents/pynacl-master/nacl/__pycache__/_cffi__x89766aa6x20a28d1e.so': libsodium.so.0: cannot open shared object file: No such file or directory
I can skip the tests and it will build without errors. However, they resurface in attempts to import things from nacl:
payton@sidony:~/Documents/pynacl-master$ python
Python 2.7.3 (default, Sep 26 2012, 21:51:14)
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import nacl.utils
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "nacl/utils.py", line 4, in <module>
from . import nacl
File "nacl/nacl.py", line 77, in <module>
lib = ffi.verify("#include <sodium.h>", libraries=["sodium"])
File "/usr/local/lib/python2.7/dist-packages/cffi-0.5-py2.7-linux-x86_64.egg/cffi/api.py", line 305, in verify
lib = self.verifier.load_library()
File "/usr/local/lib/python2.7/dist-packages/cffi-0.5-py2.7-linux-x86_64.egg/cffi/verifier.py", line 69, in load_library
return self._load_library()
File "/usr/local/lib/python2.7/dist-packages/cffi-0.5-py2.7-linux-x86_64.egg/cffi/verifier.py", line 149, in _load_library
return self._vengine.load_library()
File "/usr/local/lib/python2.7/dist-packages/cffi-0.5-py2.7-linux-x86_64.egg/cffi/vengine_cpy.py", line 123, in load_library
raise ffiplatform.VerificationError(error)
cffi.ffiplatform.VerificationError: importing '/home/payton/Documents/pynacl-master/nacl/__pycache__/_cffi__x89766aa6x20a28d1e.so': libsodium.so.0: cannot open shared object file: No such file or directory
sudo apt-get install build-essentials python-dev python-setuptools libffi-dev cython git
cd Documents
Here I downloaded a libsodium tarball (0.3) and built with
./configure && make && make check && sudo make install
then continued setting up...
git clone https://github.com/dstufft/pynacl.git
cd pynacl
python setup.py test
I verified that libsodium was correctly installed by building and running this program:
#include <stdio.h>
#include <sodium.h>
int main ()
{
printf("Hello world!\n");
return 0;
}
via
gcc hello.c -o hello -lsodium
./hello
To further verify it I built some other programs that used it extensively which would be too much to paste here, but I don't think that is where the problem is.
The docstring suggests the nonce should be passed:
def decrypt(self, ciphertext, nonce=None, encoder=encoding.RawEncoder):
"""
Decrypts the ciphertext using the given nonce and returns the
plaintext message.
:param ciphertext: [:class:`bytes`] The encrypted message to decrypt
:param nonce: [:class:`bytes`] The nonce used when encrypting the
ciphertext
<...>
On the other hand, the documentation example omits the nonce when calling decrypt()
, which works as advertised.
I'm guessing nacl/sodium attach the nonce into the encrypted message? should probably modify decrypt()
's signature accordingly if that's the case.
Since this is under pyca now, it should probably point here :)
Hi,
I'm giving box.decrypt() random data, and I expect that with high probability I will get CryptoError. (Because the ciphertext should contain an authenticator, and it should be hard to generate a valid ciphertext).
When using box.decrypt() for short random data, I get ValueError. (Which I think is a wrong behaviour). If I use it for longer random data, I get CryptoError (Which I consider to be the correct expected behaviour).
I include here my ipython transcript that shows how to reproduce this behaviour.
I'm using python 3.4 on Ubuntu 14.04 over PC, if it matters.
In [28]: import nacl.secret
In [29]: import nacl.utils
In [30]: key = nacl.utils.random(nacl.secret.SecretBox.KEY_SIZE)
In [31]: box = nacl.secret.SecretBox(key)
In [32]: message = b'This is the plaintext'
In [33]: nonce = nacl.utils.random(nacl.secret.SecretBox.NONCE_SIZE)
In [34]: encrypted = box.encrypt(message,nonce)
In [35]: plaintext = box.decrypt(encrypted)
In [36]: plaintext
Out[36]: b'This is the plaintext'
In [37]: box.decrypt(b'Short')
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-37-3326120b0dc5> in <module>()
----> 1 box.decrypt(b'Short')
/home/real/.virtualenvs/mep_backend/lib/python3.4/site-packages/nacl/secret.py in decrypt(self, ciphertext, nonce, encoder)
113 if len(nonce) != self.NONCE_SIZE:
114 raise ValueError(
--> 115 "The nonce must be exactly %s bytes long" % self.NONCE_SIZE,
116 )
117
ValueError: The nonce must be exactly 24 bytes long
In [38]: box.decrypt(b'This is some longer data')
---------------------------------------------------------------------------
CryptoError Traceback (most recent call last)
<ipython-input-38-f837d208f3d7> in <module>()
----> 1 box.decrypt(b'This is some longer data')
/home/real/.virtualenvs/mep_backend/lib/python3.4/site-packages/nacl/secret.py in decrypt(self, ciphertext, nonce, encoder)
117
118 plaintext = nacl.bindings.crypto_secretbox_open(ciphertext,
--> 119 nonce, self._key)
120
121 return plaintext
/home/real/.virtualenvs/mep_backend/lib/python3.4/site-packages/nacl/bindings/crypto_secretbox.py in crypto_secretbox_open(ciphertext, nonce, key)
72 if lib.crypto_secretbox_open(
73 plaintext, padded, len(padded), nonce, key) != 0:
---> 74 raise CryptoError("Decryption failed. Ciphertext failed verification")
75
76 plaintext = lib.ffi.buffer(plaintext, len(padded))
CryptoError: Decryption failed. Ciphertext failed verification
Okay, so here's how I have it building against Windows with the changes in #164:
C:\libsodium
C:\libsodium\include
(this is required for Python 2.7 but not other releases)builds/msvc/vs2010/libsodium
), set the target to static release, then build it. You can then use the resulting .lib
to statically link.With those prerequisites out of the way you can then do something like this to build:
@set SODIUM_INSTALL=system
@set PYNACL_SODIUM_STATIC=1
@set LIB="C:\libsodium\path\to\static\lib\you\need";%LIB%
@set INCLUDE="C:\libsodium\include";%INCLUDE%
pip install .
(The PYNACL_SODIUM_STATIC
flag is required if you want to link against the static libraries, but not if you want to use dynamic. If you use dynamic you'll need to drop the .lib
file in the appropriate place post-install though and building a wheel will be a more involved process)
The next release of pynacl will ship static windows wheels by default so this is only necessary for users who don't want to wait or want to develop this project on windows.
in the encrypt/decrypt example at : http://pynacl.readthedocs.org/en/latest/secret.html#example
The decrypt call is not using the nonce as it should
Currently PyNaCl obtains a list of header files using glob.glob()
, then calls ffi.cdef()
for each header file. This breaks horribly at runtime if the order of glob()
is different from what it was at build time (which may happen with some file systems, or after restoring a backup), resulting in very cryptic errors at runtime, even though the build/install step succeeded just fine:
python -m nacl.public
Traceback (most recent call last):
File "/usr/lib/python2.7/runpy.py", line 162, in _run_module_as_main
"__main__", fname, loader, pkg_name)
File "/usr/lib/python2.7/runpy.py", line 72, in _run_code
exec code in run_globals
File "/home/uws/.virtualenvs/38aee272d0994fde/lib/python2.7/site-packages/PyNaCl-0.2.3-py2.7-linux-x86_64.egg/nacl/public.py", line 17, in <module>
import nacl.c
File "/home/uws/.virtualenvs/38aee272d0994fde/local/lib/python2.7/site-packages/PyNaCl-0.2.3-py2.7-linux-x86_64.egg/nacl/c/__init__.py", line 16, in <module>
from nacl.c.crypto_box import (
File "/home/uws/.virtualenvs/38aee272d0994fde/local/lib/python2.7/site-packages/PyNaCl-0.2.3-py2.7-linux-x86_64.egg/nacl/c/crypto_box.py", line 23, in <module>
crypto_box_SECRETKEYBYTES = lib.crypto_box_secretkeybytes()
File "/home/uws/.virtualenvs/38aee272d0994fde/local/lib/python2.7/site-packages/PyNaCl-0.2.3-py2.7-linux-x86_64.egg/nacl/_lib/__init__.py", line 76, in __getattr__
self._lib = self.ffi.verifier.load_library()
File "/home/uws/.virtualenvs/38aee272d0994fde/local/lib/python2.7/site-packages/cffi-0.7.2-py2.7-linux-x86_64.egg/cffi/verifier.py", line 68, in load_library
self.compile_module()
File "/home/uws/.virtualenvs/38aee272d0994fde/local/lib/python2.7/site-packages/PyNaCl-0.2.3-py2.7-linux-x86_64.egg/nacl/_lib/__init__.py", line 71, in _compile_module
raise RuntimeError("Cannot compile module during runtime")
RuntimeError: Cannot compile module during runtime
Under the hood CFFI generates file names like _cffi__xd64d2119xefb54d7c.so
at compile time, and tries to load a different file at runtime. The reason for this is that the CRC32 part of the file name is based on (among other things) a concatenation of the strings passed fo ffi.cdef()
, in the order it was called.
The fix is to always .cdef()
the headers in the same order.
We were chatting about this on twitter a few days ago.. I've got an app for which I'd like to use nacl, and pynacl/libsodium looks like the best approach. But I'd like to make the build process for my app really easy (for developers). Which means I'd like them to be able to checkout my source code, run a few commands, and have a functioning program. I'm doing this by building a virtualenv and using pip install
to populate it with my app's dependencies.
But pynacl needs libsodium installed in a place where CFFI can find it, and it seems like that means /usr/lib or /usr/local/lib (and include/), which is a drag: my prospective developers would have to start with unpacking the libsodium tarball and then a ./configure && make && sudo make install
, scribbling over global directories in the process. After that, they could probably use pip to install the deps and get a working pynacl that references /usr/local/lib/libsodium.a .
One approach I've taken (with the other pynacl: https://github.com/warner/pynacl , in particular the "embed" branch) is to copy the nacl source code into the bindings project tree, then either hand-write the C-API glue code, or use SWIG. That's a drag, but it lets all the right compiler flags get used, and the result is a single .so file that doesn't reference anything else. And pip works (I think).
Doing that with this pynacl would mean running libsodium's ./configure
, then copying all the .h and .c files into the tree, then writing glue code. Ick.
Another possibility is copying those files into the tree, then telling CFFI to include (concatenate?) all of them when building the .so, instead of using a libraries=
argument to ffi.verify
. I have no idea if that would work.
Another crazy idea is to first build and install libsodium into the nacl
directory, using ./configure --prefix=./nacl && make && make install
, so you wind up with nacl/nacl.py
and nacl/lib/libsodium.so
and nacl/include/sodium.h
. Then you update setup.py to convince it to install those extra lib/include files as if they were source files. Then you modify nacl.py to look next to itself for the headers and libs. If you change setup.py's build
target to run configure and make
, I think the result would be pip-installable, at least on a system which has make
and the right compilers.
Any other thoughts on how we might make it easier to use pynacl from other projects?
In the upcoming v0.3.0 release, the ordering of arguments in the crypto_
API is being changed to match upstream. I suggest also renaming nacl.c
itself in order to fail loudly for users of that API, rather than quietly changing behavior between releases.
Ideas for the new name:
nacl.real
-- because it's the real nacl interfacenacl.crypto
-- because all of the functions start with crypto_
nacl.std
-- because it's the standard interface documented at http://nacl.cr.yp.to/@reaperhulk said: "At some point we should probably talk about what merge model we want to follow for this project"
Tell me more!
It would be useful to expose the crypto_generichash
method (Blake2b).
Working on a project now that calls for Blake2b, but that doesn't seem to be exposed anywhere.
A script using PyNaCl prints the following warning:
/Library/Python/2.7/site-packages/cffi/vengine_cpy.py:166: UserWarning: reimporting '_cffi__xe8229e48xefb54d7c' might overwrite older definitions
% (self.verifier.get_module_name()))
This example is from Mac OS X, but it happened on OpenBSD as well. The culprit is the nacl module's init.py, which has a state variable that seems intended to track whether the module is initialized, but the variable is never modified. I'll create a pull request that fixes this.
In [28]: box = nacl.secret.SecretBox(key)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-28-a37494c8a1fd> in <module>()
----> 1 box = nacl.secret.SecretBox(key)
/usr/local/lib/python2.7/dist-packages/PyNaCl-0.1.0-py2.7-linux-x86_64.egg/nacl/secret.pyc in __init__(self, key, encoder)
47 key = encoder.decode(key)
48
---> 49 if len(key) != self.KEY_SIZE:
50 raise ValueError("The key must be exactly %s bytes long" %
51 nacl.lib.crypto_secretbox_KEYBYTES)
TypeError: object of type 'PrivateKey' has no len()
Built from commit fa71dfbea5496a9be8477c8c133845ed3eb05656
on branch master
.
Right now pynacl won't compile on windows. We should fix that!
Observing this on FreeBSD.
It would be beneficial to have a clear example of handling messages not feasible to load to memory fully: the simplest use case would be encrypting/decrypting a file.
How could the secret key encryption example be adapted for file encryption?
Should a file or stream be read in chunks (obviously) and each of the chunk be encrypted with a separate box.encrypt
call or there's a better way?
Sodium has recently added the ability to select optimized implementations of the various routines. In order to support this (and newer versions of Sodium) PyNaCl will need to call sodium_init
prior to doing any work with Sodium, sodium_reinit
anytime a fork happens, and sodium_shutdown
before exiting the program.
Hello,
I'm wondering is there any way to get a progress indicator for the nacl.signing.SigningKey.generate()
function ?
I'm willing to do also a patch of libsodium if necessary to get a progress indication.
I prefer the "high-level" OOP-ish API, of course, but while comparing the low-level exposed libsodium functions (e.g. crypto_box()
) against the upstream libraries and other language bindings, I noticed that the PyNaCl arguments appear in a different order:
crypto_box(&ciphertext, &msg, msglen, &nonce, &pubkey, &secretkey)
crypto_box(&ciphertext, &msg, msglen, &nonce, &pubkey, &secretkey)
ct = crypto_box(msg, nonce, pubkey, secretkey)
ct = crypto_box(secretkey, pubkey, msg, nonce)
I don't know how they got flipped, but we should probably either flip them back (so anyone looking at the upstream NaCl or libsodium docs will correctly intuit how it's supposed to work), or document the heck out of them.
As part of the 0.4.0 release process we should triage the issues we want to tackle for 0.5.0. This issue is just to remind us to do that before releasing 0.4.0.
I believe these are privacy (IND-CPA, -CCA, and NM-CPA) and integrity (INT-PTXT and INT-CTXT), but this should be verified and included in the docs.
It might be a good idea to define an ABC that all the classes in the nacl.encoding
module implement. It will then be possible to do a isinstance
check on all the places that takes a encoder as a parameter to make sure no one passes in anything stupid.
Thoughts?
Hi, aes256 gcm is a popular mode of of operation for the symmetric key cryptographic block ciphers. It is a recommendation for Block Cipher Modes of Operation of NIST and offical standards. GCM mode has been used in many area, such as IEEE 802.1AE , ipsec, ssh, tls etc. A lot of applications plan to adopt gcm mode of operation. So support ase256 gcm will be very promising.
Do you have interest in support aes256 gcm? I have submitted a pull request for aes256 gcm support. Could you please give some suggestions or review it. Thanks...
"# Will raise nacl.signing.BadSignatureError if the signature check fails"
should be
"# Will raise nacl.exceptions.BadSignatureError if the signature check fails"
In #73 @lvh noticed that #77 removed a bunch of docstrings, in favor of separate .rst files. Are we cool with this? I agree with @lvh that docstrings are awfully handy. (I hadn't realized that removing the "autodoc" code was related to removing docstrings).
Personally, I'm -0 on removing docstrings. I like having API summaries in the docstrings, and then longer-form prose/tutorial/examples in the standalone files.
I'll volunteer to write docstrings if someone tells me what format I should use. Maybe they'd be easier to write/maintain if they don't need to be machine-readable?
The nacl.c
Python module in PyNaCl 0.2.3 implements an API that appears to be the standard "NaCl" API, but actually permutes its arguments and return values in a way that is both surprising and confusing to developers who are familiar with the NaCl C and C++ APIs.
A useful thing about NaCl, as proposed by D.J.Bernstein et al., is that it provides a notation for certain cryptographic operations that is easy to understand both for programmers and academics. One can read c = crypto_box(m, n, pk, sk)
in an academic paper or a protocol design document, understand what it means, and simply transcribe it into code. This is a great way to avoid costly transcription errors such as the ECDSA nonce reuse bug that affected PlayStation 3.
So, going from the standard NaCl documentation, the following code should work:
from nacl.c import *
k = randombytes(crypto_secretbox_KEYBYTES)
n = randombytes(crypto_secretbox_NONCEBYTES)
m = b'TheQuickBrownFoxJumps...'
c = crypto_secretbox(m,n,k)
Surprisingly, it fails:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "[...]/python3.4/site-packages/nacl/c/crypto_secretbox.py", line 37, in crypto_secretbox
raise ValueError("Invalid key")
ValueError: Invalid key
Worse, the following code raises no exception, and quietly assigns the public key to sk
and the private key to pk
:
pk, sk = crypto_box_keypair()
This is a security disaster waiting to happen. PyNaCl calls itself "NaCl" and provides exactly the same function names as NaCl does, but those functions do not behave the same as they do in NaCl.
Here's a table showing the dfferences between the crypto_*
API as documented by NaCl and as implemented in PyNaCl (I've Pythonified the NaCl API as indicated to ease the comparison, but I think you'll agree that it follows logically from the NaCl documentation):
nacl.cr.yp.to documentation | pynacl implementation |
---|---|
pk, sk = crypto_box_keypair(); /* inferred */ | sk, pk = crypto_box_keypair() |
c = crypto_box(m,n,pk,sk); | c = crypto_box(sk,pk,m,n) |
m = crypto_box_open(c,n,pk,sk); | m = crypto_box_open(sk,pk,c,n) |
k = crypto_box_beforenm(pk,sk); /* inferred */ | k = crypto_box_beforenm(sk,pk) |
c = crypto_box_afternm(m,n,k); /* inferred */ | c = crypto_box_afternm(k,m,n) |
m = crypto_box_open_afternm(c,n,k); /* inferred */ | m = crypto_box_open_afternm(k,c,n) |
q = crypto_scalarmult(n,p); | ## not implemented ## |
q = crypto_scalarmult_base(n); | q = crypto_scalarmult_base(n) |
pk, sk = crypto_sign_keypair(); /* inferred */ | sk, pk = crypto_sign_keypair() |
sm = crypto_sign(m,sk); | sm = crypto_sign(sk,m) |
m = crypto_sign_open(sm,pk); | m = crypto_sign_open(pk,sm) |
/* not documented */ | sk, pk = crypto_sign_seed_keypair(seed) |
c = crypto_secretbox(m,n,k); | c = crypto_secretbox(k,m,n) |
m = crypto_secretbox_open(c,n,k); | m = crypto_secretbox_open(k,c,n) |
c = crypto_stream(clen,n,k); | ## not implemented ## |
c = crypto_stream_xor(m,n,k); | ## not implemented ## |
a = crypto_auth(m,k); | ## not implemented ## |
crypto_auth_verify(a,m,k); | ## not implemented ## |
a = crypto_onetimeauth(m,k); | ## not implemented ## |
crypto_onetimeauth_verify(a,m,k); | ## not implemented ## |
h = crypto_hash(m); | h = crypto_hash(m) |
h = crypto_hash_sha256(m); | h = crypto_hash_sha256(m) |
h = crypto_hash_sha512(m); | h = crypto_hash_sha512(m) |
/* not documented */ | x = randombytes(size) |
crypto_verify_16(x,y); | ## not implemented ## |
crypto_verify_32(x,y); | ## not implemented ## |
Of note:
At this point, the nacl.c
module should be removed and replaced with a differently-named module that implements the real NaCl interface.
There are a number of places where the api expects a nonce. Ideally a nonce should never be reused. However DJB has stated for both Symmetrical and Asymmetrical encryption that with a random nonce the collision risk is negligible[1][2].
Currently PyNaCl documentation has lots of warnings but given with the "Crypto without the sharp edges" ideal should PyNaCl by default generate a random nonce? This will need a resolution to https://github.com/dstufft/pynacl/issues/20 or will need to change the encrypt()
function to return a tuple of (nonce, ciphertext)
.
[1] http://nacl.cr.yp.to/box.html
[2] http://nacl.cr.yp.to/secretbox.html
We don't actually wrap NaCl anymore and instead we depend on libsodium. Sodium started out as just a portable NaCl but it now includes things that NaCl doesn't. Additionally the NaCl name is easy to confuse with google's Native Client.
This looks similar to #62 but is occurring in a build I made today which presumably has the fix in it. Indeed, the package contains _cffi_fix
, so is there perhaps a leftover issue remaining?
Note the reimport is coming from my local build directory which is somehow still being linked to by the site-package version:
brandon@ubuntu:~/sites/griffin/clients/python/nacl$ python client.py
/usr/local/src/pynacl-0.2.3/.eggs/cffi-0.8.6-py2.7-linux-x86_64.egg/cffi/vengine_cpy.py:177: UserWarning: reimporting '_cffi__x6bd3e85dx794f2fab' might overwrite older definitions
% (self.verifier.get_module_name()))
I'm using public keys as identifiers and need a way to check two such identifiers for equality. Now, the way the keys are stored internally by PyNaCl varies among the different key classes (nacl.public.PublicKey
, nacl.public.VerifyKey
, nacl.public.SigningKey
, …) and I really don't want to rely on that. Hence, a magic method __eq__()
would be a great thing to have.
I will probably add it myself in the coming days and create a pull request. Just wanted to write it down in the meantime.
This page is mostly empty with a "System Message: ERROR" in it.
https://github.com/pyca/pynacl/blob/master/docs/api/hash.rst
Hello,
I'm tring to freeze my app. It's using pynacl.
I added "nacl" as a package, but when I try to launch it, it asks cffi to build the code and I get :
distutils.errors.DistutilsPlatformError: invalid Python installation: unable to open /include/python3.4m/pyconfig.h (No such file or directory)
Is it possible to prebuilt nacl so that it an be included in the freeze package ?
PyNaCl installs fine using pip
, but when imported it bugs out saying it can't find a file called sodium.h
.
From my understanding, PyNaCl includes libsodium and doesn't need it to be pre-installed on the system. I also tried pre-installing it just to make sure, and got the same error. I also verified that sodium.h
was found in my LD_LIBRARY_PATH
, but no matter what I do I seem to get the same error.
Has anybody ever seen this before?
If you would like to reproduce it the exact environment (Heroku) you can do so by running:
git init
echo "PyNaCl" > requirements.txt
echo "cffi" >> requirements.txt
heroku create --buildpack git://github.com/kennethjiang/heroku-buildpack-python-libffi.git
git add .
git commit -m "test"
git push heroku master
heroku run 'python -c "import nacl.hash"'
The full content of the error I get is as follows:
~ $ python -c "import nacl.hash"
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c:185:20: error: sodium.h: No such file or directory
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c: In function ‘_cffi_f_crypto_box’:
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c:269: warning: implicit declaration of function ‘crypto_box’
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c: In function ‘_cffi_f_crypto_box_afternm’:
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c:345: warning: implicit declaration of function ‘crypto_box_afternm’
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c: In function ‘_cffi_f_crypto_box_beforenm’:
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c:402: warning: implicit declaration of function ‘crypto_box_beforenm’
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c: In function ‘_cffi_f_crypto_box_beforenmbytes’:
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c:416: warning: implicit declaration of function ‘crypto_box_beforenmbytes’
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c: In function ‘_cffi_f_crypto_box_boxzerobytes’:
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c:430: warning: implicit declaration of function ‘crypto_box_boxzerobytes’
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c: In function ‘_cffi_f_crypto_box_keypair’:
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c:474: warning: implicit declaration of function ‘crypto_box_keypair’
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c: In function ‘_cffi_f_crypto_box_noncebytes’:
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c:488: warning: implicit declaration of function ‘crypto_box_noncebytes’
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c: In function ‘_cffi_f_crypto_box_open’:
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c:577: warning: implicit declaration of function ‘crypto_box_open’
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c: In function ‘_cffi_f_crypto_box_open_afternm’:
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c:653: warning: implicit declaration of function ‘crypto_box_open_afternm’
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c: In function ‘_cffi_f_crypto_box_publickeybytes’:
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c:667: warning: implicit declaration of function ‘crypto_box_publickeybytes’
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c: In function ‘_cffi_f_crypto_box_secretkeybytes’:
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c:681: warning: implicit declaration of function ‘crypto_box_secretkeybytes’
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c: In function ‘_cffi_f_crypto_box_zerobytes’:
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c:695: warning: implicit declaration of function ‘crypto_box_zerobytes’
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c: In function ‘_cffi_f_crypto_hash’:
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c:745: warning: implicit declaration of function ‘crypto_hash’
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c: In function ‘_cffi_f_crypto_hash_sha256’:
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c:795: warning: implicit declaration of function ‘crypto_hash_sha256’
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c: In function ‘_cffi_f_crypto_hash_sha256_bytes’:
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c:809: warning: implicit declaration of function ‘crypto_hash_sha256_bytes’
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c: In function ‘_cffi_f_crypto_hash_sha512’:
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c:859: warning: implicit declaration of function ‘crypto_hash_sha512’
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c: In function ‘_cffi_f_crypto_hash_sha512_bytes’:
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c:873: warning: implicit declaration of function ‘crypto_hash_sha512_bytes’
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c: In function ‘_cffi_f_crypto_scalarmult_base’:
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c:917: warning: implicit declaration of function ‘crypto_scalarmult_base’
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c: In function ‘_cffi_f_crypto_scalarmult_bytes’:
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c:931: warning: implicit declaration of function ‘crypto_scalarmult_bytes’
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c: In function ‘_cffi_f_crypto_scalarmult_scalarbytes’:
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c:945: warning: implicit declaration of function ‘crypto_scalarmult_scalarbytes’
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c: In function ‘_cffi_f_crypto_secretbox’:
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c:1021: warning: implicit declaration of function ‘crypto_secretbox’
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c: In function ‘_cffi_f_crypto_secretbox_boxzerobytes’:
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c:1035: warning: implicit declaration of function ‘crypto_secretbox_boxzerobytes’
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c: In function ‘_cffi_f_crypto_secretbox_keybytes’:
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c:1049: warning: implicit declaration of function ‘crypto_secretbox_keybytes’
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c: In function ‘_cffi_f_crypto_secretbox_noncebytes’:
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c:1063: warning: implicit declaration of function ‘crypto_secretbox_noncebytes’
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c: In function ‘_cffi_f_crypto_secretbox_open’:
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c:1139: warning: implicit declaration of function ‘crypto_secretbox_open’
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c: In function ‘_cffi_f_crypto_secretbox_zerobytes’:
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c:1153: warning: implicit declaration of function ‘crypto_secretbox_zerobytes’
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c: In function ‘_cffi_f_crypto_sign’:
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c:1229: warning: implicit declaration of function ‘crypto_sign’
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c: In function ‘_cffi_f_crypto_sign_bytes’:
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c:1243: warning: implicit declaration of function ‘crypto_sign_bytes’
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c: In function ‘_cffi_f_crypto_sign_keypair’:
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c:1287: warning: implicit declaration of function ‘crypto_sign_keypair’
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c: In function ‘_cffi_f_crypto_sign_open’:
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c:1363: warning: implicit declaration of function ‘crypto_sign_open’
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c: In function ‘_cffi_f_crypto_sign_publickeybytes’:
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c:1377: warning: implicit declaration of function ‘crypto_sign_publickeybytes’
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c: In function ‘_cffi_f_crypto_sign_secretkeybytes’:
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c:1391: warning: implicit declaration of function ‘crypto_sign_secretkeybytes’
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c: In function ‘_cffi_f_crypto_sign_seed_keypair’:
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c:1448: warning: implicit declaration of function ‘crypto_sign_seed_keypair’
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c: In function ‘_cffi_f_randombytes’:
.heroku/python/lib/python2.7/site-packages/nacl/_lib/__pycache__/_cffi__xac3ef8b2x44e2af4a.c:1484: warning: implicit declaration of function ‘randombytes’
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/app/.heroku/python/lib/python2.7/site-packages/nacl/hash.py", line 17, in <module>
import nacl.c
File "/app/.heroku/python/lib/python2.7/site-packages/nacl/c/__init__.py", line 16, in <module>
from nacl.c.crypto_box import (
File "/app/.heroku/python/lib/python2.7/site-packages/nacl/c/crypto_box.py", line 23, in <module>
crypto_box_SECRETKEYBYTES = lib.crypto_box_secretkeybytes()
File "/app/.heroku/python/lib/python2.7/site-packages/nacl/_lib/__init__.py", line 73, in __getattr__
self._lib = self.ffi.verifier.load_library()
File "/app/.heroku/python/lib/python2.7/site-packages/cffi/verifier.py", line 74, in load_library
self._compile_module()
File "/app/.heroku/python/lib/python2.7/site-packages/cffi/verifier.py", line 139, in _compile_module
outputfilename = ffiplatform.compile(tmpdir, self.get_extension())
File "/app/.heroku/python/lib/python2.7/site-packages/cffi/ffiplatform.py", line 25, in compile
outputfilename = _build(tmpdir, ext)
File "/app/.heroku/python/lib/python2.7/site-packages/cffi/ffiplatform.py", line 51, in _build
raise VerificationError('%s: %s' % (e.__class__.__name__, e))
cffi.ffiplatform.VerificationError: CompileError: command 'gcc' failed with exit status 1
~ $
Thanks!
It would be easier to verify that I haven't modified the bundled libsodium if it was a tarball instead of it being unpacked.
So as directed by your developer, /u/kingkilr, I'm asking you to add a way for users to access the parameters of DH key exchange.
There might be other use cases too, but at least in the one I'm working on where all key-exchange related data received needs to be manually typed on another computer, accessing the DH shared secret, (or the public encryption box's key derived from shared secret) would make it much easier (and more secure) for the users when they don't also have to write additional nonce, ciphertext and tag.
The reason I can't continuously use public key crypto box is lack of forward secrecy. So I want to use PyNaCl secret key crypto after key exchange, and refresh the shared secret key using HKDF similar to Silent Circle's SCIMP between messages.
Markus
The documentation generates both key pair objects in the same program.
skbob = PrivateKey.generate()
pkbob = skbob.public_key
skalice = PrivateKey.generate()
pkalice = skalice.public_key
Once public key has been generated, the documentation says
# the public key can be given to anyone wishing to send Bob an encrypted message
There is however no documentation about how to I could import public key of Alice into Bob's client. I succeeded in this by doing
bobPrivateKey = PrivateKey.generate()
bobPublicKey = bobPrivateKey.public_key
alicePrivateKey = PrivateKey.generate()
alicePublicKey = alicePrivateKey.public_key
alicePublicKey.__init__(getPublicKey())
box = Box(bobPrivateKey, alicePublicKey)
but I'm not sure whether creating the temporary object is the correct way. Could you advice on how public key is supposed to be imported?
Thank You.
Steps to reproduce: build with env CFLAGS="-fuse-ld=gold -flto"
or similar.
Result:
[127.0.0.1] out: make[2]: Entering directory `/tmp/pip-build-2VDruN/pynacl/build/temp.linux-x86_64-2.7/test/default'
[127.0.0.1] out: make aead_aes256gcm aead_chacha20poly1305 auth auth2 auth3 auth5 auth6 auth7 box box2 box7 box8 box_easy box_easy2 box_seal box_seed chacha20 core1 core2 core3 core4 core5 core6 ed25519_convert generichash generichas
h2 generichash3 hash hash3 onetimeauth onetimeauth2 onetimeauth7 pwhash pwhash_scrypt_ll randombytes scalarmult scalarmult2 scalarmult5 scalarmult6 scalarmult7 secretbox secretbox2 secretbox7 secretbox8 secretbox_easy secretbox_easy2 shor
thash sign sodium_core sodium_utils sodium_version stream stream2 stream3 stream4 verify1 sodium_utils2 sodium_utils3
[127.0.0.1] out: make[3]: Entering directory `/tmp/pip-build-2VDruN/pynacl/build/temp.linux-x86_64-2.7/test/default'
[127.0.0.1] out: CC aead_aes256gcm.o
[127.0.0.1] out: CCLD aead_aes256gcm
[127.0.0.1] out: /usr/lib/gcc/x86_64-linux-gnu/4.8/include/tmmintrin.h: In function 'blake2b_compress_sse41':
[127.0.0.1] out: /usr/lib/gcc/x86_64-linux-gnu/4.8/include/tmmintrin.h:136:45: error: '__builtin_ia32_pshufb128' needs isa option -m32 -mssse3
[127.0.0.1] out: return (__m128i) __builtin_ia32_pshufb128 ((__v16qi)__X, (__v16qi)__Y);
[127.0.0.1] out: ^
[127.0.0.1] out: /usr/lib/gcc/x86_64-linux-gnu/4.8/include/tmmintrin.h:136:45: error: '__builtin_ia32_pshufb128' needs isa option -m32 -mssse3
[127.0.0.1] out: return (__m128i) __builtin_ia32_pshufb128 ((__v16qi)__X, (__v16qi)__Y);
[127.0.0.1] out: ^
[127.0.0.1] out: /usr/lib/gcc/x86_64-linux-gnu/4.8/include/tmmintrin.h:136:45: error: '__builtin_ia32_pshufb128' needs isa option -m32 -mssse3
[127.0.0.1] out: return (__m128i) __builtin_ia32_pshufb128 ((__v16qi)__X, (__v16qi)__Y);
[127.0.0.1] out: ^
[127.0.0.1] out: /usr/lib/gcc/x86_64-linux-gnu/4.8/include/tmmintrin.h:136:45: error: '__builtin_ia32_pshufb128' needs isa option -m32 -mssse3
[127.0.0.1] out: return (__m128i) __builtin_ia32_pshufb128 ((__v16qi)__X, (__v16qi)__Y);
... continues for a bit ...
[127.0.0.1] out: /usr/lib/gcc/x86_64-linux-gnu/4.8/include/tmmintrin.h:185:3: error: '__builtin_ia32_palignr128' needs isa option -m32 -mssse3
[127.0.0.1] out: return (__m128i) __builtin_ia32_palignr128 ((__v2di)__X,
[127.0.0.1] out: ^
[127.0.0.1] out: lto-wrapper: gcc returned 1 exit status
[127.0.0.1] out: /usr/bin/ld.gold: fatal error: lto-wrapper failed
[127.0.0.1] out: collect2: error: ld returned 1 exit status
[127.0.0.1] out: make[3]: *** [aead_aes256gcm] Error 1
Ran into this problem when importing nacl.public, after installing through PyPI. I think I've solved it now, but posting for comments and future reference. System: OSX 10.8.3.
import nacl.public
Traceback (most recent call last):
File "", line 1, in
File "/usr/local/Cellar/python/2.7.5/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/PyNaCl-0.1.0-py2.7-macosx-10.8-x86_64.egg/nacl/public.py", line 6, in
from . import nacl, encoding
File "/usr/local/Cellar/python/2.7.5/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/PyNaCl-0.1.0-py2.7-macosx-10.8-x86_64.egg/nacl/nacl.py", line 77, in
lib = ffi.verify("#include <sodium.h>", libraries=["sodium"])
File "/Users/mark/org/src/cffi/cffi/api.py", line 311, in verify
lib = self.verifier.load_library()
File "/Users/mark/org/src/cffi/cffi/verifier.py", line 68, in load_library
self.compile_module()
File "/Users/mark/org/src/cffi/cffi/verifier.py", line 55, in compile_module
self._write_source()
File "/Users/mark/org/src/cffi/cffi/verifier.py", line 117, in _write_source
file = open(self.sourcefilename, 'w')
IOError: [Errno 2] No such file or directory: '/usr/local/Cellar/python/2.7.5/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/PyNaCl-0.1.0-py2.7-macosx-10.8-x86_64.egg/nacl/pycache/_cffi__xc7279a62x20a28d1e.c'
The problem persisted when installed directly from sources, however, when running the python process as root there was no error. Also, when installing with sudo python setup.py develop
, running python as the user owning the source folder didn't cause any error.
After debugging the issue and searching online, I found a section in the cffi docs, with which I managed to solve the issue, by adding
ffi.verify("...", ext_package='nacl')
to the setup.py file.
Curve25519 requires some bits in the secret key to bet set/cleared, and NaCl/libsodium do that clearing automatically when they do curve multiplication. That means that some bits in the input are ignored, and it's possible to have different-looking keys that are functionally the same.
PyNaCl's PrivateKey.encode()
method isn't aware of this detail; the input bytes are returned exactly as they were given to __init__()
. So it's possible to have two PrivateKey
objects that look different but result in the same public key. Here's an example.
Should __init__()
mask the private key before storing it? It's hard for me to imagine this really mattering in practice, but it might be slightly more correct.
Dear pynacl developers:
Thank you very much for this library!
I request that pynacl expose the "generic hash" function from
libsodium (https://download.libsodium.org/doc/hashing/generic_hashing.html).
This is, of course, BLAKE2!
Reasons:
Changelog:
@dstufft where is that mailing list? And how does readthedocs.org get updated?
Despite the fact that the RbNaCl guys use "secret-key encryption", I think symmetric-key encryption is a more appropriate term.
It looks like src/nacl/c/crypto_scalarmult.c
offers the crypto_scalarmult_base()
function (which takes a buffer-encoded integer and multiplies it by the standard base point), but doesn't expose the more general crypto_scalarmult()
function (which takes an integer and a point, and returns a new point). The latter is necessary to do low-level DH agreement, like for the Axolotl triple-DH ratchet, when it's not embedded inside a high-level crypto_box()
function.
I'll work on a patch.
Incidentally, the names exposed in src/nacl/c/__init__.py
are a bit weird: it imports names from submodules that shadow the submodule itself. Like crypto_secretbox
here:
from nacl.c.crypto_secretbox import (
crypto_secretbox_KEYBYTES, crypto_secretbox_NONCEBYTES,
crypto_secretbox_ZEROBYTES, crypto_secretbox_BOXZEROBYTES,
crypto_secretbox, crypto_secretbox_open,
)
When I add crypto_scalarmult()
to src/nacl/c/crypto_scalarmult.py
, we'll have another instance of this.
If the intention is that import nacl.c
should be enough to access everything exported by all modules in src/nacl/c/*.py
, I'm cool with that, although maybe the imports in __init__.py
should be relative? (from .crypto_secretbox import ...
?)
So it can't be reran, resulting in an error:
running install
running build
running build_py
running build_clib
error: [Errno 17] File exists: '/tmp/pynacl/build/temp.linux-x86_64-2.7'
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.