WIP: Optimizations with reference return types.

This commit is contained in:
attermann 2023-11-20 10:26:14 -07:00
parent 9f1602067d
commit d09331ec0e
23 changed files with 104 additions and 59 deletions

View File

@ -11,7 +11,7 @@ namespace RNS { namespace Cryptography {
class AES_128_CBC {
public:
static inline Bytes encrypt(const Bytes &plaintext, const Bytes &key, const Bytes &iv) {
static inline const Bytes encrypt(const Bytes &plaintext, const Bytes &key, const Bytes &iv) {
CBC<AES128> cbc;
cbc.setKey(key.data(), key.size());
cbc.setIV(iv.data(), iv.size());
@ -20,7 +20,7 @@ namespace RNS { namespace Cryptography {
return ciphertext;
}
static inline Bytes decrypt(const Bytes &ciphertext, const Bytes &key, const Bytes &iv) {
static inline const Bytes decrypt(const Bytes &ciphertext, const Bytes &key, const Bytes &iv) {
CBC<AES128> cbc;
cbc.setKey(key.data(), key.size());
cbc.setIV(iv.data(), iv.size());

View File

@ -30,7 +30,7 @@ namespace RNS { namespace Cryptography {
return Ptr(new Ed25519PublicKey(publicKey));
}
inline Bytes public_bytes() {
inline const Bytes &public_bytes() {
return _publicKey;
}
@ -75,7 +75,7 @@ namespace RNS { namespace Cryptography {
return Ptr(new Ed25519PrivateKey(privateKey));
}
inline Bytes private_bytes() {
inline const Bytes &private_bytes() {
return _privateKey;
}
@ -84,7 +84,7 @@ namespace RNS { namespace Cryptography {
return Ed25519PublicKey::from_public_bytes(_publicKey);
}
inline Bytes sign(const Bytes &message) {
inline const Bytes sign(const Bytes &message) {
//zreturn _sk.sign(message);
Bytes signature;
Ed25519::sign(signature.writable(64), _privateKey.data(), _publicKey.data(), message.data(), message.size());

View File

@ -49,7 +49,7 @@ bool Fernet::verify_hmac(const Bytes &token) {
return (received_hmac == expected_hmac);
}
Bytes Fernet::encrypt(const Bytes &data) {
const Bytes Fernet::encrypt(const Bytes &data) {
debug("Fernet::encrypt: plaintext length: " + std::to_string(data.size()));
Bytes iv = random(16);
@ -76,7 +76,7 @@ Bytes Fernet::encrypt(const Bytes &data) {
}
Bytes Fernet::decrypt(const Bytes &token) {
const Bytes Fernet::decrypt(const Bytes &token) {
debug("Fernet::decrypt: token length: " + std::to_string(token.size()));
if (token.size() < 48) {

View File

@ -22,7 +22,7 @@ namespace RNS { namespace Cryptography {
static const uint8_t FERNET_OVERHEAD = 48; // Bytes
public:
static inline Bytes generate_key() { return random(32); }
static inline const Bytes generate_key() { return random(32); }
public:
Fernet(const Bytes &key);
@ -30,8 +30,8 @@ namespace RNS { namespace Cryptography {
public:
bool verify_hmac(const Bytes &token);
Bytes encrypt(const Bytes &data);
Bytes decrypt(const Bytes &token);
const Bytes encrypt(const Bytes &data);
const Bytes decrypt(const Bytes &token);
private:
Bytes _signing_key;

View File

@ -5,7 +5,7 @@
using namespace RNS;
Bytes RNS::Cryptography::hkdf(size_t length, const Bytes &derive_from, const Bytes &salt /*= {Bytes::NONE}*/, const Bytes &context /*= {Bytes::NONE}*/) {
const Bytes RNS::Cryptography::hkdf(size_t length, const Bytes &derive_from, const Bytes &salt /*= {Bytes::NONE}*/, const Bytes &context /*= {Bytes::NONE}*/) {
if (length <= 0) {
throw std::invalid_argument("Invalid output key length");

View File

@ -4,6 +4,6 @@
namespace RNS { namespace Cryptography {
Bytes hkdf(size_t length, const Bytes &derive_from, const Bytes &salt = {Bytes::NONE}, const Bytes &context = {Bytes::NONE});
const Bytes hkdf(size_t length, const Bytes &derive_from, const Bytes &salt = {Bytes::NONE}, const Bytes &context = {Bytes::NONE});
} }

View File

@ -99,7 +99,7 @@ namespace RNS { namespace Cryptography {
msg: bytes or buffer, Input message.
digest: The underlying hash algorithm to use.
*/
inline Bytes digest(const Bytes &key, const Bytes &msg, HMAC::Digest digest = HMAC::DIGEST_SHA256) {
inline const Bytes digest(const Bytes &key, const Bytes &msg, HMAC::Digest digest = HMAC::DIGEST_SHA256) {
HMAC hmac(key, msg, digest);
hmac.update(msg);
return hmac.digest();

View File

@ -14,7 +14,7 @@ uses Python's internal SHA-256 implementation. All SHA-256
calls in RNS end up here.
*/
Bytes RNS::Cryptography::sha256(const Bytes &data) {
const Bytes RNS::Cryptography::sha256(const Bytes &data) {
//extreme("Cryptography::sha256: data: " + data.toHex() );
SHA256 digest;
digest.reset();
@ -25,7 +25,7 @@ Bytes RNS::Cryptography::sha256(const Bytes &data) {
return hash;
}
Bytes RNS::Cryptography::sha512(const Bytes &data) {
const Bytes RNS::Cryptography::sha512(const Bytes &data) {
SHA512 digest;
digest.reset();
digest.update(data.data(), data.size());

View File

@ -6,7 +6,7 @@
namespace RNS { namespace Cryptography {
Bytes sha256(const Bytes &data);
Bytes sha512(const Bytes &data);
const Bytes sha256(const Bytes &data);
const Bytes sha512(const Bytes &data);
} }

View File

@ -13,13 +13,13 @@ namespace RNS { namespace Cryptography {
static const size_t BLOCKSIZE = 16;
static inline Bytes pad(const Bytes &data, size_t bs = BLOCKSIZE) {
static inline const Bytes pad(const Bytes &data, size_t bs = BLOCKSIZE) {
Bytes padded(data);
inplace_pad(padded, bs);
return padded;
}
static inline Bytes unpad(const Bytes &data, size_t bs = BLOCKSIZE) {
static inline const Bytes unpad(const Bytes &data, size_t bs = BLOCKSIZE) {
Bytes unpadded(data);
inplace_unpad(unpadded, bs);
return unpadded;

View File

@ -8,7 +8,7 @@
namespace RNS { namespace Cryptography {
// return vector specified length of random bytes
inline Bytes random(size_t length) {
inline const Bytes random(size_t length) {
Bytes rand;
RNG.rand(rand.writable(length), length);
return rand;

View File

@ -111,11 +111,11 @@ namespace RNS { namespace Cryptography {
}
/*
inline Bytes private_bytes() {
inline const Bytes private_bytes() {
return _pack_number(_a);
}
*/
inline Bytes private_bytes() {
inline const Bytes &private_bytes() {
return _privateKey;
}
@ -130,7 +130,7 @@ namespace RNS { namespace Cryptography {
}
/*
inline Bytes exchange(const Bytes &peer_public_key) {
inline const Bytes exchange(const Bytes &peer_public_key) {
if isinstance(peer_public_key, bytes):
peer_public_key = X25519PublicKey.from_public_bytes(peer_public_key)
@ -168,7 +168,7 @@ namespace RNS { namespace Cryptography {
return shared
}
*/
inline Bytes exchange(const Bytes &peer_public_key) {
inline const Bytes exchange(const Bytes &peer_public_key) {
debug("X25519PublicKey::exchange: public key: " + _publicKey.toHex());
debug("X25519PublicKey::exchange: peer public key: " + peer_public_key.toHex());
debug("X25519PublicKey::exchange: pre private key: " + _privateKey.toHex());

View File

@ -314,7 +314,7 @@ Encrypts information for ``RNS.Destination.SINGLE`` or ``RNS.Destination.GROUP``
:param plaintext: A *bytes-like* containing the plaintext to be encrypted.
:raises: ``ValueError`` if destination does not hold a necessary key for encryption.
*/
Bytes Destination::encrypt(const Bytes &data) {
const Bytes Destination::encrypt(const Bytes &data) {
assert(_object);
debug("Destination::encrypt: encrypting data...");
@ -348,7 +348,7 @@ Decrypts information for ``RNS.Destination.SINGLE`` or ``RNS.Destination.GROUP``
:param ciphertext: *Bytes* containing the ciphertext to be decrypted.
:raises: ``ValueError`` if destination does not hold a necessary key for decryption.
*/
Bytes Destination::decrypt(const Bytes &data) {
const Bytes Destination::decrypt(const Bytes &data) {
assert(_object);
debug("Destination::decrypt: decrypting data...");
@ -382,7 +382,7 @@ Signs information for ``RNS.Destination.SINGLE`` type destination.
:param message: *Bytes* containing the message to be signed.
:returns: A *bytes-like* containing the message signature, or *None* if the destination could not sign the message.
*/
Bytes Destination::sign(const Bytes &message) {
const Bytes Destination::sign(const Bytes &message) {
assert(_object);
if (_object->_type == SINGLE && _object->_identity) {
return _object->_identity.sign(message);

View File

@ -144,16 +144,16 @@ namespace RNS {
void receive(const Packet &packet);
void incoming_link_request(const Bytes &data, const Packet &packet);
Bytes encrypt(const Bytes &data);
Bytes decrypt(const Bytes &data);
Bytes sign(const Bytes &message);
const Bytes encrypt(const Bytes &data);
const Bytes decrypt(const Bytes &data);
const Bytes sign(const Bytes &message);
// getters/setters
inline Type::Destination::types type() const { assert(_object); return _object->_type; }
inline Type::Destination::directions direction() const { assert(_object); return _object->_direction; }
inline Type::Destination::proof_strategies proof_strategy() const { assert(_object); return _object->_proof_strategy; }
inline Bytes hash() const { assert(_object); return _object->_hash; }
inline Bytes link_id() const { assert(_object); return _object->_link_id; }
inline const Bytes &hash() const { assert(_object); return _object->_hash; }
inline const Bytes &link_id() const { assert(_object); return _object->_link_id; }
inline uint16_t mtu() const { assert(_object); return _object->_mtu; }
inline void mtu(uint16_t mtu) { assert(_object); _object->_mtu = mtu; }
inline Type::Link::status status() const { assert(_object); return _object->_status; }

View File

@ -132,7 +132,7 @@ Encrypts information for the identity.
:returns: Ciphertext token as *bytes*.
:raises: *KeyError* if the instance does not hold a public key.
*/
Bytes Identity::encrypt(const Bytes &plaintext) {
const Bytes Identity::encrypt(const Bytes &plaintext) {
assert(_object);
debug("Identity::encrypt: encrypting data...");
if (!_object->_pub) {
@ -172,7 +172,7 @@ Decrypts information for the identity.
:returns: Plaintext as *bytes*, or *None* if decryption fails.
:raises: *KeyError* if the instance does not hold a private key.
*/
Bytes Identity::decrypt(const Bytes &ciphertext_token) {
const Bytes Identity::decrypt(const Bytes &ciphertext_token) {
assert(_object);
debug("Identity::decrypt: decrypting data...");
if (!_object->_prv) {
@ -226,7 +226,7 @@ Signs information by the identity.
:returns: Signature as *bytes*.
:raises: *KeyError* if the instance does not hold a private key.
*/
Bytes Identity::sign(const Bytes &message) {
const Bytes Identity::sign(const Bytes &message) {
assert(_object);
if (!_object->_sig_prv) {
throw std::runtime_error("Signing failed because identity does not hold a private key");

View File

@ -48,7 +48,7 @@ namespace RNS {
/*
:returns: The public key as *bytes*
*/
inline Bytes get_public_key() {
inline const Bytes get_public_key() {
assert(_object);
return _object->_pub_bytes + _object->_sig_pub_bytes;
}
@ -65,7 +65,7 @@ namespace RNS {
:param data: Data to be hashed as *bytes*.
:returns: SHA-256 hash as *bytes*
*/
static inline Bytes full_hash(const Bytes &data) {
static inline const Bytes full_hash(const Bytes &data) {
return Cryptography::sha256(data);
}
/*
@ -74,7 +74,7 @@ namespace RNS {
:param data: Data to be hashed as *bytes*.
:returns: Truncated SHA-256 hash as *bytes*
*/
static inline Bytes truncated_hash(const Bytes &data) {
static inline const Bytes truncated_hash(const Bytes &data) {
//return Identity.full_hash(data)[:(Identity.TRUNCATED_HASHLENGTH//8)]
return full_hash(data).left(Type::Identity::TRUNCATED_HASHLENGTH/8);
}
@ -84,18 +84,18 @@ namespace RNS {
:param data: Data to be hashed as *bytes*.
:returns: Truncated SHA-256 hash of random data as *bytes*
*/
static inline Bytes get_random_hash() {
static inline const Bytes get_random_hash() {
return truncated_hash(Cryptography::random(Type::Identity::TRUNCATED_HASHLENGTH/8));
}
static bool validate_announce(const Packet &packet);
inline Bytes get_salt() { assert(_object); return _object->_hash; }
inline Bytes get_context() { return {Bytes::NONE}; }
inline const Bytes get_salt() { assert(_object); return _object->_hash; }
inline const Bytes get_context() { return {Bytes::NONE}; }
Bytes encrypt(const Bytes &plaintext);
Bytes decrypt(const Bytes &ciphertext_token);
Bytes sign(const Bytes &message);
const Bytes encrypt(const Bytes &plaintext);
const Bytes decrypt(const Bytes &ciphertext_token);
const Bytes sign(const Bytes &message);
bool validate(const Bytes &signature, const Bytes &message);
// CBA following default for reference value requires inclusiion of header
//void prove(const Packet &packet, const Destination &destination = {Type::NONE});
@ -103,11 +103,11 @@ namespace RNS {
void prove(const Packet &packet);
// getters/setters
inline Bytes encryptionPrivateKey() const { assert(_object); return _object->_prv_bytes; }
inline Bytes signingPrivateKey() const { assert(_object); return _object->_sig_prv_bytes; }
inline Bytes encryptionPublicKey() const { assert(_object); return _object->_prv_bytes; }
inline Bytes signingPublicKey() const { assert(_object); return _object->_sig_prv_bytes; }
inline Bytes hash() const { assert(_object); return _object->_hash; }
inline const Bytes &encryptionPrivateKey() const { assert(_object); return _object->_prv_bytes; }
inline const Bytes &signingPrivateKey() const { assert(_object); return _object->_sig_prv_bytes; }
inline const Bytes &encryptionPublicKey() const { assert(_object); return _object->_prv_bytes; }
inline const Bytes &signingPublicKey() const { assert(_object); return _object->_sig_prv_bytes; }
inline const Bytes &hash() const { assert(_object); return _object->_hash; }
inline std::string hexhash() const { assert(_object); return _object->_hexhash; }
inline std::string toString() const { assert(_object); return "{Identity:" + _object->_hash.toHex() + "}"; }

View File

@ -1,5 +1,6 @@
#include "Interface.h"
#include "Identity.h"
#include "Transport.h"
using namespace RNS;
@ -20,6 +21,10 @@ using namespace RNS::Type::Interface;
_object->_txb += data.size();
}
const Bytes Interface::get_hash() const {
return Identity::full_hash({toString()});
}
void Interface::process_announce_queue() {
/*
if not hasattr(self, "announce_cap"):

View File

@ -65,7 +65,7 @@ namespace RNS {
}
public:
inline Bytes get_hash() const { /*return Identity::full_hash();*/ return {}; }
const Bytes get_hash() const;
void process_announce_queue();
inline void detach() {}
@ -87,13 +87,13 @@ namespace RNS {
inline bool FWD() const { assert(_object); return _object->_FWD; }
inline bool RPT() const { assert(_object); return _object->_RPT; }
inline std::string name() const { assert(_object); return _object->_name; }
inline Bytes ifac_identity() const { assert(_object); return _object->_ifac_identity; }
inline const Bytes &ifac_identity() const { assert(_object); return _object->_ifac_identity; }
inline Type::Interface::modes mode() const { assert(_object); return _object->_mode; }
inline uint32_t bitrate() const { assert(_object); return _object->_bitrate; }
inline uint64_t announce_allowed_at() const { assert(_object); return _object->_announce_allowed_at; }
inline void announce_allowed_at(uint64_t announce_allowed_at) { assert(_object); _object->_announce_allowed_at = announce_allowed_at; }
inline float announce_cap() const { assert(_object); return _object->_announce_cap; }
inline std::list<AnnounceEntry> announce_queue() const { assert(_object); return _object->_announce_queue; }
inline std::list<AnnounceEntry> &announce_queue() const { assert(_object); return _object->_announce_queue; }
virtual inline std::string toString() const { assert(_object); return "Interface[" + _object->_name + "]"; }

View File

@ -15,10 +15,10 @@ Packet::Packet(const Destination &destination, const Interface &attached_interfa
if (_object->_destination) {
extreme("Creating packet with destination...");
// CBA TODO handle NONE
if (transport_type == -1) {
transport_type = Type::Transport::BROADCAST;
}
// CBA Should never see empty transport_type
//if (transport_type == NONE) {
// transport_type = Type::Transport::BROADCAST;
//}
// following moved to object constructor to avoid extra NONE object
//_destination = destination;
_object->_header_type = header_type;

View File

@ -190,9 +190,9 @@ namespace RNS {
inline uint8_t flags() const { assert(_object); return _object->_flags; }
inline uint8_t hops() const { assert(_object); return _object->_hops; }
inline void hops(uint8_t hops) { assert(_object); _object->_hops = hops; }
inline Bytes packet_hash() const { assert(_object); return _object->_packet_hash; }
inline Bytes destination_hash() const { assert(_object); return _object->_destination_hash; }
inline Bytes transport_id() const { assert(_object); return _object->_transport_id; }
inline const Bytes &packet_hash() const { assert(_object); return _object->_packet_hash; }
inline const Bytes &destination_hash() const { assert(_object); return _object->_destination_hash; }
inline const Bytes &transport_id() const { assert(_object); return _object->_transport_id; }
inline void transport_id(const Bytes &transport_id) { assert(_object); _object->_transport_id = transport_id; }
inline const Bytes &raw() const { assert(_object); return _object->_raw; }
inline const Bytes &data() const { assert(_object); return _object->_data; }

View File

@ -6,6 +6,21 @@
#include <map>
#include <assert.h>
//void testBytesDefault(const RNS::Bytes &bytes = {RNS::Bytes::NONE}) {
void testBytesDefault(const RNS::Bytes &bytes = {}) {
assert(!bytes);
assert(bytes.size() == 0);
assert(bytes.data() == nullptr);
}
RNS::Bytes ref("Test");
const RNS::Bytes &testBytesReference() {
// NOTE: Can NOT return local instance as reference!!!
//RNS::Bytes ref("Test");
RNS::extreme("returning...");
return ref;
}
void testBytes() {
RNS::Bytes bytes;
@ -50,14 +65,23 @@ void testBytes() {
RNS::extreme("assign prebuf: " + prebuf.toString());
RNS::extreme("assign postbuf: " + postbuf.toString());
// test string assignment
bytes = "Foo";
assert(bytes.size() == 3);
assert(memcmp(bytes.data(), "Foo", bytes.size()) == 0);
// test string addition
bytes = prebuf + postbuf;
assert(bytes.size() == 11);
assert(memcmp(bytes.data(), "Hello World", bytes.size()) == 0);
// test string constructor
{
RNS::Bytes str("Foo");
assert(str.size() == 3);
assert(memcmp(str.data(), "Foo", str.size()) == 0);
}
// test left in range
{
RNS::Bytes left(bytes.left(5));
@ -205,6 +229,20 @@ void testBytes() {
assert(bytes.data() == nullptr);
}
// function default argument
RNS::head("TestBytes: function default argument", RNS::LOG_EXTREME);
testBytesDefault();
// function reference return
RNS::head("TestBytes: function reference return", RNS::LOG_EXTREME);
{
RNS::Bytes test = testBytesReference();
RNS::extreme("returned");
assert(test);
assert(test.size() == 4);
assert(memcmp(test.data(), "Test", test.size()) == 0);
}
// TODO test comparison
}

View File

@ -224,6 +224,7 @@ namespace RNS {
static void exit_handler();
private:
// CBA MUST use references to interfaces here in order for virtul overrides for send/receive to work
//static std::set<std::reference_wrapper<const Interface>, std::less<const Interface>> _interfaces; // All active interfaces
static std::list<std::reference_wrapper<Interface>> _interfaces; // All active interfaces
static std::set<Destination> _destinations; // All active destinations

View File

@ -144,6 +144,7 @@ void setup() {
//testReference();
//testCrypto();
RNS::extreme("Finished running tests");
//return;
#endif
//std::stringstream test;