def test_box_wrong_lengths(): A_pubkey, A_secretkey = c.crypto_box_keypair() with pytest.raises(ValueError): c.crypto_box(b"abc", "\x00", A_pubkey, A_secretkey) with pytest.raises(ValueError): c.crypto_box(b"abc", "\x00" * c.crypto_box_NONCEBYTES, b"", A_secretkey) with pytest.raises(ValueError): c.crypto_box(b"abc", "\x00" * c.crypto_box_NONCEBYTES, A_pubkey, b"") with pytest.raises(ValueError): c.crypto_box_open(b"", b"", b"", b"") with pytest.raises(ValueError): c.crypto_box_open(b"", "\x00" * c.crypto_box_NONCEBYTES, b"", b"") with pytest.raises(ValueError): c.crypto_box_open(b"", "\x00" * c.crypto_box_NONCEBYTES, A_pubkey, b"") with pytest.raises(ValueError): c.crypto_box_beforenm(b"", b"") with pytest.raises(ValueError): c.crypto_box_beforenm(A_pubkey, b"") with pytest.raises(ValueError): c.crypto_box_afternm(b"", b"", b"") with pytest.raises(ValueError): c.crypto_box_afternm(b"", b"\x00" * c.crypto_box_NONCEBYTES, b"") with pytest.raises(ValueError): c.crypto_box_open_afternm(b"", b"", b"") with pytest.raises(ValueError): c.crypto_box_open_afternm(b"", b"\x00" * c.crypto_box_NONCEBYTES, b"")
def test_box_wrong_lengths(): A_pubkey, A_secretkey = c.crypto_box_keypair() with pytest.raises(ValueError): c.crypto_box(b"abc", "\x00", A_pubkey, A_secretkey) with pytest.raises(ValueError): c.crypto_box( b"abc", "\x00" * c.crypto_box_NONCEBYTES, b"", A_secretkey) with pytest.raises(ValueError): c.crypto_box( b"abc", "\x00" * c.crypto_box_NONCEBYTES, A_pubkey, b"") with pytest.raises(ValueError): c.crypto_box_open(b"", b"", b"", b"") with pytest.raises(ValueError): c.crypto_box_open(b"", "\x00" * c.crypto_box_NONCEBYTES, b"", b"") with pytest.raises(ValueError): c.crypto_box_open(b"", "\x00" * c.crypto_box_NONCEBYTES, A_pubkey, b"") with pytest.raises(ValueError): c.crypto_box_beforenm(b"", b"") with pytest.raises(ValueError): c.crypto_box_beforenm(A_pubkey, b"") with pytest.raises(ValueError): c.crypto_box_afternm(b"", b"", b"") with pytest.raises(ValueError): c.crypto_box_afternm(b"", b"\x00" * c.crypto_box_NONCEBYTES, b"") with pytest.raises(ValueError): c.crypto_box_open_afternm(b"", b"", b"") with pytest.raises(ValueError): c.crypto_box_open_afternm(b"", b"\x00" * c.crypto_box_NONCEBYTES, b"")
def test_box(): 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_pubkey, B_secretkey = c.crypto_box_keypair() k1 = c.crypto_box_beforenm(B_pubkey, A_secretkey) assert len(k1) == c.crypto_box_BEFORENMBYTES k2 = c.crypto_box_beforenm(A_pubkey, B_secretkey) assert tohex(k1) == tohex(k2) message = b"message" nonce = b"\x01" * c.crypto_box_NONCEBYTES ct1 = c.crypto_box_afternm(message, nonce, k1) assert len(ct1) == len(message) + c.crypto_box_BOXZEROBYTES ct2 = c.crypto_box(message, nonce, B_pubkey, A_secretkey) assert tohex(ct2) == tohex(ct1) m1 = c.crypto_box_open(ct1, nonce, A_pubkey, B_secretkey) assert m1 == message m2 = c.crypto_box_open_afternm(ct1, nonce, k1) assert m2 == message with pytest.raises(CryptoError): c.crypto_box_open(message + b"!", nonce, A_pubkey, A_secretkey)
def test_box(): 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_pubkey, B_secretkey = c.crypto_box_keypair() k1 = c.crypto_box_beforenm(B_pubkey, A_secretkey) assert len(k1) == c.crypto_box_BEFORENMBYTES k2 = c.crypto_box_beforenm(A_pubkey, B_secretkey) assert tohex(k1) == tohex(k2) message = b"message" nonce = b"\x01" * c.crypto_box_NONCEBYTES ct1 = c.crypto_box_afternm(message, nonce, k1) assert len(ct1) == len(message) + c.crypto_box_BOXZEROBYTES ct2 = c.crypto_box(message, nonce, B_pubkey, A_secretkey) assert tohex(ct2) == tohex(ct1) m1 = c.crypto_box_open(ct1, nonce, A_pubkey, B_secretkey) assert m1 == message m2 = c.crypto_box_open_afternm(ct1, nonce, k1) assert m2 == message with pytest.raises(CryptoError): c.crypto_box_open( message + b"!", nonce, A_pubkey, A_secretkey)
def create_server_accept(self): """ create a server accept crypto envelope. this envelope is sent from the server to the client. it's math representation is the following: Box_{box_secret}(data_to_box) where: data_to_box = Sign_B( K | H | hash(crypto_scalarmult(b_priv, a_pub)) box_secret = hash([ K | crypto_scalarmult(b_priv, a_pub) | crypto_scalarmult(B_priv, a_pub) | crypto_scalarmult(b_priv, A_pub) ]) H = A_pub | Sign_A_priv( K | B_pub | hash(crypto_scalarmult(b_priv, a_pub))) K = <<this is the application key>> """ message_to_sign = self.application_key + self._client_vouch + self._hashed_secret signed_message = self.local_signing_key.private_key.sign( message_to_sign) message_to_box = signed_message.signature local_longterm_sharedsecret = crypto_scalarmult( bytes(self.local_signing_key.private_key.to_curve25519_private_key( )), bytes(self._remote_ephemeral_pub_key)) remote_longterm_sharedsecret = crypto_scalarmult( bytes(self.local_ephemeral_key.private_key), bytes(self.remote_longterm_pub_key.to_curve25519_public_key())) to_hash = self.application_key + self._secret + local_longterm_sharedsecret + remote_longterm_sharedsecret hasher = hashlib.sha256() hasher.update(to_hash) box_secret = hasher.digest() self._shared_secret = box_secret nonce = b"\x00" * 24 return crypto_box_afternm(message_to_box, nonce, box_secret)
def create_client_auth(self): """ this is the client authentication cryptographic envelope which the client sends to the server. it's mathematical representation is as follows: Box_{box_secret}(data_to_box) where: box_secret = hash([K | crypto_scalarmult(a_priv, b_pub) | crypto_scalarmult(a_priv, B_pub)]) data_to_box = A_pub | Sign_A_priv( K | B_pub | hash(crypto_scalarmult(a_priv, b_pub))) K = <<this is the application key>> """ hasher = hashlib.sha256() scalar = crypto_scalarmult(bytes(self.local_ephemeral_key.private_key), bytes(self._remote_ephemeral_pub_key)) hasher.update(scalar) hashed_value = hasher.digest() signed_message = self.local_signing_key.private_key.sign( self.application_key + bytes(self.remote_longterm_pub_key) + bytes(hashed_value)) message_to_box = bytes( self.local_signing_key.public_key) + signed_message.signature self._client_auth = message_to_box scalar_remote_longterm = crypto_scalarmult( bytes(self.local_ephemeral_key.private_key), bytes(self.remote_longterm_pub_key.to_curve25519_public_key())) hasher = hashlib.sha256() # XXX hasher.update(self.application_key + scalar + scalar_remote_longterm) box_secret = hasher.digest() nonce = b"\x00" * 24 return crypto_box_afternm(message_to_box, nonce, box_secret)
def generate_client_auth(self): """Generate box[K|a*b|a*B](H)""" nonce = b"\x00" * 24 # return box(K | a * b | a * B)[H] return crypto_box_afternm(self.hello, nonce, self.box_secret)
def generate_accept(self): okay = self.local_key.sign(self.application_key + self.hello + self.shared_hash).signature d = crypto_box_afternm(okay, b'\x00' * 24, self.box_secret) return d
def crypto_box_afternm(self, m, n, k): return bindings.crypto_box_afternm(m, n, k)