Skip to content
Snippets Groups Projects
Commit e0fc13b9 authored by Brian Warner's avatar Brian Warner
Browse files

fix raw crypto_box API

parent 660a7ba6
Branches
Tags
No related merge requests found
......@@ -30,41 +30,41 @@ crypto_box_BEFORENMBYTES = lib.crypto_box_beforenmbytes()
def crypto_box_keypair():
"""
Returns a randomly generated secret and public key.
Returns a randomly generated public and secret key.
:rtype: (bytes(secret_key), bytes(public_key))
:rtype: (bytes(public_key), bytes(secret_key))
"""
sk = lib.ffi.new("unsigned char[]", crypto_box_SECRETKEYBYTES)
pk = lib.ffi.new("unsigned char[]", crypto_box_PUBLICKEYBYTES)
sk = lib.ffi.new("unsigned char[]", crypto_box_SECRETKEYBYTES)
if lib.crypto_box_keypair(pk, sk) != 0:
raise CryptoError("An error occurred trying to generate the keypair")
return (
lib.ffi.buffer(sk, crypto_box_SECRETKEYBYTES)[:],
lib.ffi.buffer(pk, crypto_box_PUBLICKEYBYTES)[:],
lib.ffi.buffer(sk, crypto_box_SECRETKEYBYTES)[:],
)
def crypto_box(sk, pk, message, nonce):
def crypto_box(message, nonce, pk, sk):
"""
Encrypts and returns a message ``message`` using the secret key ``sk``,
public key ``pk``, and the nonce ``nonce``.
:param sk: bytes
:param pk: bytes
:param message: bytes
:param nonce: bytes
:param pk: bytes
:param sk: bytes
:rtype: bytes
"""
if len(sk) != crypto_box_SECRETKEYBYTES:
raise ValueError("Invalid secret key")
if len(nonce) != crypto_box_NONCEBYTES:
raise ValueError("Invalid nonce size")
if len(pk) != crypto_box_PUBLICKEYBYTES:
raise ValueError("Invalid public key")
if len(nonce) != crypto_box_NONCEBYTES:
raise ValueError("Invalid nonce size")
if len(sk) != crypto_box_SECRETKEYBYTES:
raise ValueError("Invalid secret key")
padded = (b"\x00" * crypto_box_ZEROBYTES) + message
ciphertext = lib.ffi.new("unsigned char[]", len(padded))
......@@ -75,25 +75,25 @@ def crypto_box(sk, pk, message, nonce):
return lib.ffi.buffer(ciphertext, len(padded))[crypto_box_BOXZEROBYTES:]
def crypto_box_open(sk, pk, ciphertext, nonce):
def crypto_box_open(ciphertext, nonce, pk, sk):
"""
Decrypts and returns an encrypted message ``ciphertext``, using the secret
key ``sk``, public key ``pk``, and the nonce ``nonce``.
:param sk: bytes
:param pk: bytes
:param ciphertext: bytes
:param nonce: bytes
:param pk: bytes
:param sk: bytes
:rtype: bytes
"""
if len(sk) != crypto_box_SECRETKEYBYTES:
raise ValueError("Invalid secret key")
if len(nonce) != crypto_box_NONCEBYTES:
raise ValueError("Invalid nonce size")
if len(pk) != crypto_box_PUBLICKEYBYTES:
raise ValueError("Invalid public key")
if len(nonce) != crypto_box_NONCEBYTES:
raise ValueError("Invalid nonce size")
if len(sk) != crypto_box_SECRETKEYBYTES:
raise ValueError("Invalid secret key")
padded = (b"\x00" * crypto_box_BOXZEROBYTES) + ciphertext
plaintext = lib.ffi.new("unsigned char[]", len(padded))
......@@ -104,22 +104,22 @@ def crypto_box_open(sk, pk, ciphertext, nonce):
return lib.ffi.buffer(plaintext, len(padded))[crypto_box_ZEROBYTES:]
def crypto_box_beforenm(sk, pk):
def crypto_box_beforenm(pk, sk):
"""
Computes and returns the shared key for the secret key ``sk`` and the
public key ``pk``. This can be used to speed up operations where the same
Computes and returns the shared key for the public key ``pk`` and the
secret key ``sk``. This can be used to speed up operations where the same
set of keys is going to be used multiple times.
:param sk: bytes
:param pk: bytes
:param sk: bytes
:rtype: bytes
"""
if len(sk) != crypto_box_SECRETKEYBYTES:
raise ValueError("Invalid secret key")
if len(pk) != crypto_box_PUBLICKEYBYTES:
raise ValueError("Invalid public key")
if len(sk) != crypto_box_SECRETKEYBYTES:
raise ValueError("Invalid secret key")
k = lib.ffi.new("unsigned char[]", crypto_box_BEFORENMBYTES)
if lib.crypto_box_beforenm(k, pk, sk) != 0:
......@@ -128,22 +128,22 @@ def crypto_box_beforenm(sk, pk):
return lib.ffi.buffer(k, crypto_box_BEFORENMBYTES)[:]
def crypto_box_afternm(k, message, nonce):
def crypto_box_afternm(message, nonce, k):
"""
Encrypts and returns the message ``message`` using the shared key ``k`` and
the nonce ``nonce``.
:param k: bytes
:param message: bytes
:param nonce: bytes
:param k: bytes
:rtype: bytes
"""
if len(k) != crypto_box_BEFORENMBYTES:
raise ValueError("Invalid shared key")
if len(nonce) != crypto_box_NONCEBYTES:
raise ValueError("Invalid nonce")
if len(k) != crypto_box_BEFORENMBYTES:
raise ValueError("Invalid shared key")
padded = b"\x00" * crypto_box_ZEROBYTES + message
ciphertext = lib.ffi.new("unsigned char[]", len(padded))
......@@ -153,22 +153,22 @@ def crypto_box_afternm(k, message, nonce):
return lib.ffi.buffer(ciphertext, len(padded))[crypto_box_BOXZEROBYTES:]
def crypto_box_open_afternm(k, ciphertext, nonce):
def crypto_box_open_afternm(ciphertext, nonce, k):
"""
Decrypts and returns the encrypted message ``ciphertext``, using the shared
key ``k`` and the nonce ``nonce``.
:param k: bytes
:param ciphertext: bytes
:param nonce: bytes
:param k: bytes
:rtype: bytes
"""
if len(k) != crypto_box_BEFORENMBYTES:
raise ValueError("Invalid shared key")
if len(nonce) != crypto_box_NONCEBYTES:
raise ValueError("Invalid nonce")
if len(k) != crypto_box_BEFORENMBYTES:
raise ValueError("Invalid shared key")
padded = (b"\x00" * crypto_box_BOXZEROBYTES) + ciphertext
plaintext = lib.ffi.new("unsigned char[]", len(padded))
......
......@@ -114,8 +114,8 @@ class Box(encoding.Encodable, StringFixer, object):
def __init__(self, private_key, public_key):
if private_key and public_key:
self._shared_key = nacl.c.crypto_box_beforenm(
private_key.encode(encoder=encoding.RawEncoder),
public_key.encode(encoder=encoding.RawEncoder),
private_key.encode(encoder=encoding.RawEncoder),
)
else:
self._shared_key = None
......@@ -152,9 +152,9 @@ class Box(encoding.Encodable, StringFixer, object):
self.NONCE_SIZE)
ciphertext = nacl.c.crypto_box_afternm(
self._shared_key,
plaintext,
nonce,
self._shared_key,
)
encoded_nonce = encoder.encode(nonce)
......@@ -190,9 +190,9 @@ class Box(encoding.Encodable, StringFixer, object):
self.NONCE_SIZE)
plaintext = nacl.c.crypto_box_open_afternm(
self._shared_key,
ciphertext,
nonce,
self._shared_key,
)
return plaintext
......@@ -44,34 +44,28 @@ def test_secretbox():
assert msg2 == msg
def test_box():
# TODO: NaCl C++ is pk=box_keypair(sk), C is box_keypair(pk,sk)
A_secretkey, A_pubkey = c.crypto_box_keypair()
A_pubkey, A_secretkey = c.crypto_box_keypair()
assert len(A_secretkey) == c.crypto_box_SECRETKEYBYTES
assert len(A_pubkey) == c.crypto_box_PUBLICKEYBYTES
B_secretkey, B_pubkey = c.crypto_box_keypair()
B_pubkey, B_secretkey = c.crypto_box_keypair()
# TODO: NaCl is beforenm(k,pk,sk)
k1 = c.crypto_box_beforenm(A_secretkey, B_pubkey)
k1 = c.crypto_box_beforenm(B_pubkey, A_secretkey)
assert len(k1) == c.crypto_box_BEFORENMBYTES
k2 = c.crypto_box_beforenm(B_secretkey, A_pubkey)
k2 = c.crypto_box_beforenm(A_pubkey, B_secretkey)
assert hexlify(k1) == hexlify(k2)
message = "message"
nonce = "\x01" * c.crypto_box_NONCEBYTES
# TODO: NaCl is box_afternm(ct, msg, nonce, k)
ct1 = c.crypto_box_afternm(k1, message, nonce)
ct1 = c.crypto_box_afternm(message, nonce, k1)
assert len(ct1) == len(message) + c.crypto_box_BOXZEROBYTES
# TODO: NaCl is box(ct, msg, nonce, pubkey, secretkey)
ct2 = c.crypto_box(A_secretkey, B_pubkey, message, nonce)
ct2 = c.crypto_box(message, nonce, B_pubkey, A_secretkey)
assert hexlify(ct2) == hexlify(ct1)
# TODO: NaCl is open(msg, ct, nonce, pk, sk)
m1 = c.crypto_box_open(B_secretkey, A_pubkey, ct1, nonce)
m1 = c.crypto_box_open(ct1, nonce, A_pubkey, B_secretkey)
assert m1 == message
# TODO: NaCl is open_afternm(msg, ct, nonce, k)
m2 = c.crypto_box_open_afternm(k1, ct1, nonce)
m2 = c.crypto_box_open_afternm(ct1, nonce, k1)
assert m2 == message
......@@ -96,8 +90,7 @@ def test_sign():
assert msg2 == msg
def secret_scalar():
# TODO: NaCl is box_keypair(pk,sk)
secretkey, pubkey = c.crypto_box_keypair()
pubkey, secretkey = c.crypto_box_keypair()
assert len(secretkey) == c.crypto_box_SECRETKEYBYTES
assert c.crypto_box_SECRETKEYBYTES == c.crypto_scalarmult_BYTES
return secretkey, pubkey
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment