From 1b919a94899a2c7c2bc8ce962379e36698f22d28 Mon Sep 17 00:00:00 2001 From: attermann Date: Sat, 7 Oct 2023 01:03:15 -0600 Subject: [PATCH] WIP Update Cleaned up and organized test functions. Implemented Ed25519. --- src/Bytes.h | 8 + src/Cryptography/Ed25519.cpp | 3 + src/Cryptography/Ed25519.h | 97 +++++++++ src/Cryptography/X25519.cpp | 3 + src/Cryptography/X25519.h | 131 +++++++++++ src/DumbBuffer.h | 102 --------- src/Identity.cpp | 52 +++-- src/Identity.h | 31 ++- src/Log.cpp | 4 + src/Log.h | 1 + src/Reticulum.cpp | 10 + src/Reticulum.h | 3 + src/Test/Test.cpp | 22 ++ src/Test/Test.h | 13 ++ src/Test/TestBytes.cpp | 274 +++++++++++++++++++++++ src/Test/TestCrypto.cpp | 31 +++ src/Test/TestReference.cpp | 29 +++ src/main.cpp | 412 +++-------------------------------- test/test.cpp | 157 ------------- 19 files changed, 711 insertions(+), 672 deletions(-) create mode 100644 src/Cryptography/Ed25519.cpp create mode 100644 src/Cryptography/Ed25519.h create mode 100644 src/Cryptography/X25519.cpp create mode 100644 src/Cryptography/X25519.h delete mode 100644 src/DumbBuffer.h create mode 100644 src/Test/Test.cpp create mode 100644 src/Test/Test.h create mode 100644 src/Test/TestBytes.cpp create mode 100644 src/Test/TestCrypto.cpp create mode 100644 src/Test/TestReference.cpp delete mode 100644 test/test.cpp diff --git a/src/Bytes.h b/src/Bytes.h index 368a8ff..d6b32b1 100644 --- a/src/Bytes.h +++ b/src/Bytes.h @@ -20,10 +20,18 @@ namespace RNS { //typedef std::shared_ptr SharedData; using SharedData = std::shared_ptr; + public: + enum NoneConstructor { + NONE + }; + public: Bytes() { //extreme("Bytes object created from default, this: " + std::to_string((ulong)this) + ", data: " + std::to_string((ulong)_data.get())); } + Bytes(NoneConstructor none) { + //extreme("Bytes object created from NONE, this: " + std::to_string((ulong)this) + ", data: " + std::to_string((ulong)_data.get())); + } Bytes(const Bytes &bytes) { //extreme("Bytes is using shared data"); _data = bytes.shareData(); diff --git a/src/Cryptography/Ed25519.cpp b/src/Cryptography/Ed25519.cpp new file mode 100644 index 0000000..a69c397 --- /dev/null +++ b/src/Cryptography/Ed25519.cpp @@ -0,0 +1,3 @@ +#include "Ed25519.h" + +using namespace RNS::Cryptography; diff --git a/src/Cryptography/Ed25519.h b/src/Cryptography/Ed25519.h new file mode 100644 index 0000000..14e746d --- /dev/null +++ b/src/Cryptography/Ed25519.h @@ -0,0 +1,97 @@ +#pragma once + +#include "Bytes.h" + +#include + +#include + +/* + +Note that the library currently in use for Ed25519 does not support generating keys from a seed. + +*/ + +namespace RNS { namespace Cryptography { + + class Ed25519PublicKey { + + public: + Ed25519PublicKey(const Bytes &publicKey) { + _publicKey = publicKey; + } + ~Ed25519PublicKey() {} + + using Ptr = std::shared_ptr; + + public: + // creates a new instance with specified seed + static inline Ptr from_public_bytes(const Bytes &publicKey) { + return Ptr(new Ed25519PublicKey(publicKey)); + } + + inline Bytes public_bytes() { + return _publicKey; + } + + inline bool verify(const Bytes &signature, const Bytes &message) { + return Ed25519::verify(signature.data(), _publicKey.data(), message.data(), message.size()); + } + + private: + Bytes _publicKey; + + }; + + class Ed25519PrivateKey { + + public: + Ed25519PrivateKey(const Bytes &privateKey) { + if (privateKey) { + // use specified private key + _privateKey = privateKey; + } + else { + // create random private key + Ed25519::generatePrivateKey(_privateKey.writable(32)); + } + Ed25519::derivePublicKey(_publicKey.writable(32), _privateKey.data()); + } + ~Ed25519PrivateKey() {} + + using Ptr = std::shared_ptr; + + public: + // creates a new instance with a random seed + static inline Ptr generate() { + return Ptr(new Ed25519PrivateKey(Bytes::NONE)); + } + + // creates a new instance with specified seed + static inline Ptr from_private_bytes(const Bytes &privateKey) { + return Ptr(new Ed25519PrivateKey(privateKey)); + } + + inline Bytes private_bytes() { + return _privateKey; + } + + // creates a new instance of public key for this private key + inline Ed25519PublicKey::Ptr public_key() { + return Ed25519PublicKey::from_public_bytes(_publicKey); + } + + inline Bytes sign(const Bytes &message) { + //zreturn _sk.sign(message); + Bytes signature; + Ed25519::sign(signature.writable(64), _privateKey.data(), _publicKey.data(), message.data(), message.size()); + return signature; + } + + private: + Bytes _privateKey; + Bytes _publicKey; + + }; + +} } diff --git a/src/Cryptography/X25519.cpp b/src/Cryptography/X25519.cpp new file mode 100644 index 0000000..5e7cc31 --- /dev/null +++ b/src/Cryptography/X25519.cpp @@ -0,0 +1,3 @@ +#include "X25519.h" + +using namespace RNS::Cryptography; diff --git a/src/Cryptography/X25519.h b/src/Cryptography/X25519.h new file mode 100644 index 0000000..988eb6e --- /dev/null +++ b/src/Cryptography/X25519.h @@ -0,0 +1,131 @@ +#pragma once + +#include "Bytes.h" + +#include +#include + +namespace RNS { namespace Cryptography { + + class X25519PublicKey { + + public: + X25519PublicKey(const Bytes &x) { + _x = x; + } + ~X25519PublicKey() {} + + using Ptr = std::shared_ptr; + + public: + // creates a new instance with specified seed + static inline Ptr from_public_bytes(const Bytes &data) { + //return Ptr(new X25519PublicKey(_unpack_number(data))); + // MOCK + return Ptr(new X25519PublicKey(nullptr)); + } + + Bytes public_bytes() { + //return _pack_number(_x); + // MOCK + return nullptr; + } + + private: + Bytes _x; + + }; + + class X25519PrivateKey { + + public: + const float MIN_EXEC_TIME = 0.002; + const float MAX_EXEC_TIME = 0.5; + const uint8_t DELAY_WINDOW = 10; + + //zT_CLEAR = None + const uint8_t T_MAX = 0; + + public: + X25519PrivateKey(const Bytes &a) { + _a = a; + } + ~X25519PrivateKey() {} + + using Ptr = std::shared_ptr; + + public: + // creates a new instance with a random seed + static inline Ptr generate() { + //return from_private_bytes(os.urandom(32)); + // MOCK + return from_private_bytes(nullptr); + } + + // creates a new instance with specified seed + static inline Ptr from_private_bytes(const Bytes &data) { + //return Ptr(new X25519PrivateKey(_fix_secret(_unpack_number(data)))); + // MOCK + return Ptr(new X25519PrivateKey(nullptr)); + } + + inline Bytes private_bytes() { + //return _pack_number(_a); + // MOCK + return nullptr; + } + + // creates a new instance of public key for this private key + inline X25519PublicKey::Ptr public_key() { + //return X25519PublicKey::from_public_bytes(_pack_number(_raw_curve25519(9, _a))); + // MOCK + return X25519PublicKey::from_public_bytes(nullptr); + } + + inline Bytes exchange(const Bytes &peer_public_key) { +/* + if isinstance(peer_public_key, bytes): + peer_public_key = X25519PublicKey.from_public_bytes(peer_public_key) + + start = time.time() + + shared = _pack_number(_raw_curve25519(peer_public_key.x, _a)) + + end = time.time() + duration = end-start + + if X25519PrivateKey.T_CLEAR == None: + X25519PrivateKey.T_CLEAR = end + X25519PrivateKey.DELAY_WINDOW + + if end > X25519PrivateKey.T_CLEAR: + X25519PrivateKey.T_CLEAR = end + X25519PrivateKey.DELAY_WINDOW + X25519PrivateKey.T_MAX = 0 + + if duration < X25519PrivateKey.T_MAX or duration < X25519PrivateKey.MIN_EXEC_TIME: + target = start+X25519PrivateKey.T_MAX + + if target > start+X25519PrivateKey.MAX_EXEC_TIME: + target = start+X25519PrivateKey.MAX_EXEC_TIME + + if target < start+X25519PrivateKey.MIN_EXEC_TIME: + target = start+X25519PrivateKey.MIN_EXEC_TIME + + try: + time.sleep(target-time.time()) + except Exception as e: + pass + + elif duration > X25519PrivateKey.T_MAX: + X25519PrivateKey.T_MAX = duration + + return shared +*/ + return nullptr; + } + + private: + Bytes _a; + + }; + +} } diff --git a/src/DumbBuffer.h b/src/DumbBuffer.h deleted file mode 100644 index 5600dc4..0000000 --- a/src/DumbBuffer.h +++ /dev/null @@ -1,102 +0,0 @@ -#pragma once - -#include "Log.h" - -#include -#include -#include -#include -#include -#include - -#define COW - -namespace RNS { - - class Bytes { - - public: - Bytes(size_t capacity = 0) { - if (capacity > 0) { - //_vector.reserve(capacity); - _vector = std::shared_ptr>(new std::vector(capacity)); - } - else { - _vector = std::shared_ptr>(new std::vector()); - } - log("Bytes object created from default"); - } - Bytes(const Bytes &bytes, size_t capacity = 0) : Bytes(capacity) { - //append(bytes); - _vector = bytes._vector; - _owner = false; - log(std::string("Bytes object created from bytes \"") + toString() + "\""); - } - Bytes(const uint8_t *chunk, size_t size, size_t capacity = 0) : Bytes(capacity) { - append(chunk, size); - log(std::string("Bytes object created from chunk \"") + toString() + "\""); - } - Bytes(const char *string, size_t capacity = 0) : Bytes(capacity) { - append(string); - log(std::string("Bytes object created from string \"") + toString() + "\""); - } - ~Bytes() { - log(std::string("Bytes object destroyed \"") + toString() + "\""); - } - - inline Bytes& operator + (const Bytes &bytes) { - append(bytes); - return *this; - } - inline Bytes& operator += (const Bytes &bytes) { - append(bytes); - return *this; - } - inline bool operator == (const Bytes &bytes) const { - return _vector == bytes._vector; - } - inline bool operator < (const Bytes &bytes) const { - return _vector < bytes._vector; - } - - public: - inline size_t size() const { return _vector->size(); } - inline bool empty() const { return _vector->empty(); } - inline size_t capacity() const { return _vector->capacity(); } - inline const uint8_t *data() const { return _vector->data(); } - - void append(const Bytes& bytes) { - _vector->insert(_vector->end(), bytes._vector->begin(), bytes._vector->end()); - } - void append(const uint8_t *chunk, size_t size) { - _vector->insert(_vector->end(), chunk, chunk + size); - } - void append(const char* string) { - _vector->insert(_vector->end(), (uint8_t *)string, (uint8_t *)string + strlen(string)); - } - - inline std::string toString() { return {(const char*)data(), size()}; } - - private: - //std::vector _vector; - std::shared_ptr> _vector; - bool _owner = true;; - - }; - - // following array function doesn't work without size since it's past as a pointer to the array sizeof() is of the pointer - //static inline Bytes bytesFromArray(const uint8_t arr[]) { return Bytes(arr, sizeof(arr)); } - //static inline Bytes bytesFromChunk(const uint8_t *ptr, size_t len) { return Bytes(ptr, len); } - static inline Bytes bytesFromChunk(const uint8_t *ptr, size_t len) { return {ptr, len}; } - //static inline Bytes bytesFromString(const char *str) { return Bytes((uint8_t*)str, strlen(str)); } - static inline Bytes bytesFromString(const char *str) { return {(uint8_t*)str, strlen(str)}; } - //zstatic inline Bytes bytesFromInt(const int) { return {(uint8_t*)str, strlen(str)}; } - - static inline std::string stringFromBytes(const Bytes& bytes) { return {(const char*)bytes.data(), bytes.size()}; } - -} - -inline RNS::Bytes& operator << (RNS::Bytes &lhs, const RNS::Bytes &rhs) { - lhs.append(rhs); - return lhs; -} diff --git a/src/Identity.cpp b/src/Identity.cpp index 8a6ce27..88ead56 100644 --- a/src/Identity.cpp +++ b/src/Identity.cpp @@ -18,27 +18,33 @@ Identity::Identity(bool create_keys) : _object(new Object()) { void Identity::createKeys() { assert(_object); -/* - self.prv = X25519PrivateKey.generate() - self.prv_bytes = self.prv.private_bytes() + _object->_prv = Cryptography::X25519PrivateKey::generate(); + _object->_prv_bytes = _object->_prv->private_bytes(); + debug("Identity::createKeys: prv bytes: " + _object->_prv_bytes.toHex()); - self.sig_prv = Ed25519PrivateKey.generate() - self.sig_prv_bytes = self.sig_prv.private_bytes() + _object->_sig_prv = Cryptography::Ed25519PrivateKey::generate(); + _object->_sig_prv_bytes = _object->_sig_prv->private_bytes(); + debug("Identity::createKeys: sig prv bytes: " + _object->_sig_prv_bytes.toHex()); - self.pub = self.prv.public_key() - self.pub_bytes = self.pub.public_bytes() + _object->_pub = _object->_prv->public_key(); + _object->_pub_bytes = _object->_pub->public_bytes(); + debug("Identity::createKeys: pub bytes: " + _object->_pub_bytes.toHex()); - self.sig_pub = self.sig_prv.public_key() - self.sig_pub_bytes = self.sig_pub.public_bytes() -*/ + _object->_sig_pub = _object->_sig_prv->public_key(); + _object->_sig_pub_bytes = _object->_sig_pub->public_bytes(); + debug("Identity::createKeys: sig pub bytes: " + _object->_sig_pub_bytes.toHex()); update_hashes(); - //verbose("Identity keys created for " + _object->_hash.toHex()); + verbose("Identity keys created for " + _object->_hash.toHex()); } +/* +:returns: The public key as *bytes* +*/ Bytes Identity::get_public_key() { assert(_object); + return _object->_pub_bytes + _object->_sig_pub_bytes; // MOCK return "abc123"; } @@ -60,18 +66,18 @@ Signs information by the identity. */ Bytes Identity::sign(const Bytes &message) { assert(_object); -/* - if self.sig_prv != None: - try: - return self.sig_prv.sign(message) - except Exception as e: - RNS.log("The identity "+str(self)+" could not sign the requested message. The contained exception was: "+str(e), RNS.LOG_ERROR) - raise e - else: - raise KeyError("Signing failed because identity does not hold a private key") -*/ - // MOCK - return {message}; + if (_object->_sig_prv) { + try { + return _object->_sig_prv->sign(message); + } + catch (std::exception e) { + error("The identity " + toString() + " could not sign the requested message. The contained exception was: " + e.what()); + throw e; + } + } + else { + throw std::runtime_error("Signing failed because identity does not hold a private key"); + } } diff --git a/src/Identity.h b/src/Identity.h index cd4bcc6..51fee3b 100644 --- a/src/Identity.h +++ b/src/Identity.h @@ -4,6 +4,9 @@ #include "Log.h" #include "Bytes.h" #include "Cryptography/Fernet.h" +#include "Cryptography/X25519.h" +#include "Cryptography/Ed25519.h" + #include #include @@ -65,21 +68,37 @@ namespace RNS { static Bytes truncated_hash(const Bytes &data); Bytes sign(const Bytes &message); + 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 std::string hexhash() const { assert(_object); return _object->_hexhash; } + inline std::string toString() const { assert(_object); return _object->_hash.toHex(); } + private: class Object { public: - Object() { - extreme("Identity::Data object created, this: " + std::to_string((ulong)this)); - } - ~Object() { - extreme("Identity::Data object destroyed, this: " + std::to_string((ulong)this)); - } + Object() { extreme("Identity::Data object created, this: " + std::to_string((ulong)this)); } + ~Object() { extreme("Identity::Data object destroyed, this: " + std::to_string((ulong)this)); } private: + + RNS::Cryptography::X25519PrivateKey::Ptr _prv; + Bytes _prv_bytes; + + RNS::Cryptography::Ed25519PrivateKey::Ptr _sig_prv; + Bytes _sig_prv_bytes; + + RNS::Cryptography::X25519PublicKey::Ptr _pub; + Bytes _pub_bytes; + + RNS::Cryptography::Ed25519PublicKey::Ptr _sig_pub; + Bytes _sig_pub_bytes; + Bytes _hash; std::string _hexhash; + friend class Identity; }; std::shared_ptr _object; diff --git a/src/Log.cpp b/src/Log.cpp index 32d1467..d250be3 100644 --- a/src/Log.cpp +++ b/src/Log.cpp @@ -33,6 +33,10 @@ void RNS::loglevel(LogLevel level) { _level = level; } +LogLevel RNS::loglevel() { + return _level; +} + void RNS::doLog(const char* msg, LogLevel level) { if (level > _level) { return; diff --git a/src/Log.h b/src/Log.h index ca68ae7..002379b 100644 --- a/src/Log.h +++ b/src/Log.h @@ -20,6 +20,7 @@ namespace RNS { }; void loglevel(LogLevel level); + LogLevel loglevel(); void doLog(const char* msg, LogLevel level); diff --git a/src/Reticulum.cpp b/src/Reticulum.cpp index a7cead4..28f4c61 100644 --- a/src/Reticulum.cpp +++ b/src/Reticulum.cpp @@ -2,13 +2,23 @@ #include "Log.h" +#include + using namespace RNS; Reticulum::Reticulum() : _object(new Object()) { extreme("Reticulum object created"); + + // Initialkize random number generator + RNG.begin("Reticulum"); + //RNG.stir(mac_address, sizeof(mac_address)); } Reticulum::~Reticulum() { extreme("Reticulum object destroyed"); } +void Reticulum::loop() { + // Perform random number gnerator housekeeping + RNG.loop(); +} diff --git a/src/Reticulum.h b/src/Reticulum.h index 7ce2314..f8aed51 100644 --- a/src/Reticulum.h +++ b/src/Reticulum.h @@ -104,6 +104,9 @@ namespace RNS { return _object.get() != nullptr; } + public: + void loop(); + private: std::shared_ptr _object; diff --git a/src/Test/Test.cpp b/src/Test/Test.cpp new file mode 100644 index 0000000..ac05c4a --- /dev/null +++ b/src/Test/Test.cpp @@ -0,0 +1,22 @@ +#include "Test.h" + +#include "Log.h" + +void test() { + + //RNS::LogLevel loglevel = RNS::loglevel(); + //RNS::loglevel(RNS::LOG_WARNING); + + testMap(); + testBytes(); + testCowBytes(); + testObjects(); + testBytesConversion(); + + testReference(); + + testCrypto(); + + //RNS::loglevel(loglevel); + +} diff --git a/src/Test/Test.h b/src/Test/Test.h new file mode 100644 index 0000000..6016dd8 --- /dev/null +++ b/src/Test/Test.h @@ -0,0 +1,13 @@ + +void test(); + +void testMap(); +void testBytes(); +void testCowBytes(); +void testBytesConversion(); + +void testObjects(); + +void testReference(); + +void testCrypto(); diff --git a/src/Test/TestBytes.cpp b/src/Test/TestBytes.cpp new file mode 100644 index 0000000..9c92921 --- /dev/null +++ b/src/Test/TestBytes.cpp @@ -0,0 +1,274 @@ +#include + +#include "Bytes.h" +#include "Log.h" + +#include + +void testMap() +{ + const uint8_t prestr[] = "Hello"; + const uint8_t poststr[] = "World"; + + RNS::Bytes prebuf(prestr, 5); + assert(prebuf.size() == 5); + assert(memcmp(prebuf.data(), "Hello", prebuf.size()) == 0); + + RNS::Bytes postbuf(poststr, 5); + assert(postbuf.size() == 5); + assert(memcmp(postbuf.data(), "World", postbuf.size()) == 0); + + std::map map; + map.insert({prebuf, "hello"}); + map.insert({postbuf, "world"}); + assert(map.size() == 2); + + auto preit = map.find(prebuf); + assert(preit != map.end()); + assert((*preit).second.compare("hello") == 0); + if (preit != map.end()) { + RNS::extreme(std::string("found prebuf: ") + (*preit).second); + } + + auto postit = map.find(postbuf); + assert(postit != map.end()); + assert((*postit).second.compare("world") == 0); + if (postit != map.end()) { + RNS::extreme(std::string("found postbuf: ") + (*postit).second); + } + + const uint8_t newstr[] = "World"; + RNS::Bytes newbuf(newstr, 5); + assert(newbuf.size() == 5); + assert(memcmp(newbuf.data(), "World", newbuf.size()) == 0); + auto newit = map.find(newbuf); + assert(newit != map.end()); + assert((*newit).second.compare("world") == 0); + if (newit != map.end()) { + RNS::extreme(std::string("found newbuf: ") + (*newit).second); + } + + std::string str = map["World"]; + assert(str.size() == 5); + assert(str.compare("world") == 0); +} + +void testBytes() { + + RNS::Bytes bytes; + assert(!bytes); + assert(bytes.size() == 0); + assert(bytes.empty() == true); + assert(bytes.data() == nullptr); + + const uint8_t prestr[] = "Hello"; + const uint8_t poststr[] = " World"; + + RNS::Bytes prebuf(prestr, 5); + assert(prebuf); + assert(prebuf.size() == 5); + assert(memcmp(prebuf.data(), "Hello", prebuf.size()) == 0); + assert(!(bytes == prebuf)); + assert(bytes != prebuf); + assert(bytes < prebuf); + + RNS::Bytes postbuf(poststr, 6); + assert(postbuf); + assert(postbuf.size() == 6); + assert(memcmp(postbuf.data(), " World", postbuf.size()) == 0); + assert(!(postbuf == bytes)); + assert(postbuf != bytes); + assert(postbuf > bytes); + + assert(!(prebuf == postbuf)); + assert(prebuf != postbuf); + + if (prebuf == postbuf) { + RNS::extreme("bytess are the same"); + } + else { + RNS::extreme("bytess are different"); + } + + bytes += prebuf + postbuf; + assert(bytes.size() == 11); + assert(memcmp(bytes.data(), "Hello World", bytes.size()) == 0); + RNS::extreme("assign bytes: " + bytes.toString()); + RNS::extreme("assign prebuf: " + prebuf.toString()); + RNS::extreme("assign postbuf: " + postbuf.toString()); + + bytes = "Foo"; + assert(bytes.size() == 3); + assert(memcmp(bytes.data(), "Foo", bytes.size()) == 0); + + bytes = prebuf + postbuf; + assert(bytes.size() == 11); + assert(memcmp(bytes.data(), "Hello World", bytes.size()) == 0); + + // stream into empty bytes + { + RNS::Bytes strmbuf; + strmbuf << prebuf << postbuf; + RNS::extreme("stream strmbuf: " + strmbuf.toString()); + RNS::extreme("stream prebuf: " + prebuf.toString()); + RNS::extreme("stream postbuf: " + postbuf.toString()); + assert(strmbuf.size() == 11); + assert(memcmp(strmbuf.data(), "Hello World", strmbuf.size()) == 0); + assert(prebuf.size() == 5); + assert(memcmp(prebuf.data(), "Hello", prebuf.size()) == 0); + assert(postbuf.size() == 6); + assert(memcmp(postbuf.data(), " World", postbuf.size()) == 0); + } + + // stream into populated bytes + { + RNS::Bytes strmbuf("Stream "); + assert(strmbuf); + assert(strmbuf.size() == 7); + assert(memcmp(strmbuf.data(), "Stream ", strmbuf.size()) == 0); + + strmbuf << prebuf << postbuf; + RNS::extreme("stream strmbuf: " + strmbuf.toString()); + RNS::extreme("stream prebuf: " + prebuf.toString()); + RNS::extreme("stream postbuf: " + postbuf.toString()); + assert(strmbuf.size() == 18); + assert(memcmp(strmbuf.data(), "Stream Hello World", strmbuf.size()) == 0); + assert(prebuf.size() == 5); + assert(memcmp(prebuf.data(), "Hello", prebuf.size()) == 0); + assert(postbuf.size() == 6); + assert(memcmp(postbuf.data(), " World", postbuf.size()) == 0); + } + + // stream with assignment + // (this is a known and correct but perhaps unexpected and non-intuitive side-effect of assignment with stream) + { + RNS::Bytes strmbuf = prebuf << postbuf; + RNS::extreme("stream strmbuf: " + strmbuf.toString()); + RNS::extreme("stream prebuf: " + prebuf.toString()); + RNS::extreme("stream postbuf: " + postbuf.toString()); + assert(strmbuf.size() == 11); + assert(memcmp(strmbuf.data(), "Hello World", strmbuf.size()) == 0); + assert(prebuf.size() == 11); + assert(memcmp(prebuf.data(), "Hello World", prebuf.size()) == 0); + assert(postbuf.size() == 6); + assert(memcmp(postbuf.data(), " World", postbuf.size()) == 0); + } + + // test creating bytes from nullptr + { + RNS::Bytes bytes = nullptr; + assert(!bytes); + assert(bytes.size() == 0); + assert(bytes.data() == nullptr); + } + + // test creating bytes from NONE + { + RNS::Bytes bytes(RNS::Bytes::NONE); + assert(!bytes); + assert(bytes.size() == 0); + assert(bytes.data() == nullptr); + } + +} + +void testCowBytes() { + + RNS::Bytes bytes1("1"); + assert(bytes1.size() == 1); + assert(memcmp(bytes1.data(), "1", bytes1.size()) == 0); + + RNS::Bytes bytes2(bytes1); + assert(bytes2.size() == 1); + assert(memcmp(bytes2.data(), "1", bytes2.size()) == 0); + assert(bytes2.data() == bytes1.data()); + + RNS::Bytes bytes3(bytes2); + assert(bytes3.size() == 1); + assert(memcmp(bytes3.data(), "1", bytes3.size()) == 0); + assert(bytes3.data() == bytes2.data()); + + RNS::extreme("pre bytes1 ptr: " + std::to_string((uint32_t)bytes1.data()) + " data: " + bytes1.toString()); + RNS::extreme("pre bytes2 ptr: " + std::to_string((uint32_t)bytes2.data()) + " data: " + bytes2.toString()); + RNS::extreme("pre bytes3 ptr: " + std::to_string((uint32_t)bytes3.data()) + " data: " + bytes3.toString()); + + //bytes1.append("mississippi"); + //assert(bytes1.size() == 12); + //assert(memcmp(bytes1.data(), "1mississippi", bytes1.size()) == 0); + //assert(bytes1.data() != bytes2.data()); + + bytes2.append("mississippi"); + assert(bytes2.size() == 12); + assert(memcmp(bytes2.data(), "1mississippi", bytes2.size()) == 0); + assert(bytes2.data() != bytes1.data()); + + bytes3.assign("mississippi"); + assert(bytes3.size() == 11); + assert(memcmp(bytes3.data(), "mississippi", bytes3.size()) == 0); + assert(bytes3.data() != bytes2.data()); + + RNS::extreme("post bytes1 ptr: " + std::to_string((uint32_t)bytes1.data()) + " data: " + bytes1.toString()); + RNS::extreme("post bytes2 ptr: " + std::to_string((uint32_t)bytes2.data()) + " data: " + bytes2.toString()); + RNS::extreme("post bytes3 ptr: " + std::to_string((uint32_t)bytes3.data()) + " data: " + bytes3.toString()); +} + +void testBytesConversion() { + + { + RNS::Bytes bytes("Hello World"); + std::string hex = bytes.toHex(); + RNS::extreme("text: \"" + bytes.toString() + "\" upper hex: \"" + hex + "\""); + assert(hex.length() == 22); + assert(hex.compare("48656C6C6F20576F726C64") == 0); + } + { + RNS::Bytes bytes("Hello World"); + std::string hex = bytes.toHex(false); + RNS::extreme("text: \"" + bytes.toString() + "\" lower hex: \"" + hex + "\""); + assert(hex.length() == 22); + assert(hex.compare("48656c6c6f20576f726c64") == 0); + } + { + std::string hex("48656C6C6F20576F726C64"); + RNS::Bytes bytes; + bytes.assignHex(hex.c_str()); + std::string text = bytes.toString(); + RNS::extreme("hex: \"" + hex + "\" text: \"" + text + "\""); + assert(text.length() == 11); + assert(text.compare("Hello World") == 0); + } + { + std::string hex("48656c6c6f20576f726c64"); + RNS::Bytes bytes; + bytes.assignHex(hex.c_str()); + std::string text = bytes.toString(); + RNS::extreme("hex: \"" + hex + "\" text: \"" + text + "\""); + assert(text.length() == 11); + assert(text.compare("Hello World") == 0); + + bytes.assignHex(hex.c_str()); + text = bytes.toString(); + RNS::extreme("hex: \"" + hex + "\" text: \"" + text + "\""); + assert(text.length() == 11); + assert(text.compare("Hello World") == 0); + + bytes.appendHex(hex.c_str()); + text = bytes.toString(); + RNS::extreme("hex: \"" + hex + "\" text: \"" + text + "\""); + assert(text.length() == 22); + assert(text.compare("Hello WorldHello World") == 0); + } + +} + +/* +int main(void) +{ + UNITY_BEGIN(); + RUN_TEST(testMap); + RUN_TEST(testBytes); + RUN_TEST(testCowBytes); + RUN_TEST(testBytesConversion); + return UNITY_END(); +} +*/ diff --git a/src/Test/TestCrypto.cpp b/src/Test/TestCrypto.cpp new file mode 100644 index 0000000..14ff92b --- /dev/null +++ b/src/Test/TestCrypto.cpp @@ -0,0 +1,31 @@ +#include + +#include "Reticulum.h" +#include "Identity.h" +#include "Destination.h" +#include "Packet.h" +#include "Bytes.h" + +void testCrypto() { + + RNS::Reticulum reticulum; + + RNS::Identity identity; + + RNS::Destination destination(identity, RNS::Destination::IN, RNS::Destination::SINGLE, "appname", "aspects"); + //assert(encryptionPrivateKey().toHex().compare("") == ); + //assert(signingPrivateKey().toHex().compare("") == ); + //assert(encryptionPublicKey().toHex().compare("") == ); + //assert(signingPublicKey().toHex().compare("") == ); + + //Packet packet = destination.announce("appdata"); +} + +/* +int main(void) +{ + UNITY_BEGIN(); + RUN_TEST(testObjects); + return UNITY_END(); +} +*/ diff --git a/src/Test/TestReference.cpp b/src/Test/TestReference.cpp new file mode 100644 index 0000000..3e91cb4 --- /dev/null +++ b/src/Test/TestReference.cpp @@ -0,0 +1,29 @@ +#include + +#include "Reticulum.h" +#include "Bytes.h" + +void testReference() { + + RNS::Reticulum reticulum_default; + assert(reticulum_default); + + RNS::Reticulum reticulum_none(RNS::Reticulum::NONE); + assert(!reticulum_none); + + RNS::Reticulum reticulum_default_copy(reticulum_default); + assert(reticulum_default_copy); + + RNS::Reticulum reticulum_none_copy(reticulum_none); + assert(!reticulum_none_copy); + +} + +/* +int main(void) +{ + UNITY_BEGIN(); + RUN_TEST(testObjects); + return UNITY_END(); +} +*/ diff --git a/src/main.cpp b/src/main.cpp index 571f8be..c45227c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,5 +1,7 @@ //#define NDEBUG +#include "Test/Test.h" + #include "Reticulum.h" #include "Identity.h" #include "Destination.h" @@ -29,372 +31,21 @@ const char* APP_NAME = "example_utilities"; const char* fruits[] = {"Peach", "Quince", "Date", "Tangerine", "Pomelo", "Carambola", "Grape"}; const char* noble_gases[] = {"Helium", "Neon", "Argon", "Krypton", "Xenon", "Radon", "Oganesson"}; -void testMap() -{ - const uint8_t prestr[] = "Hello"; - const uint8_t poststr[] = "World"; - - RNS::Bytes prebuf(prestr, 5); - assert(prebuf.size() == 5); - assert(memcmp(prebuf.data(), "Hello", prebuf.size()) == 0); - - RNS::Bytes postbuf(poststr, 5); - assert(postbuf.size() == 5); - assert(memcmp(postbuf.data(), "World", postbuf.size()) == 0); - - std::map map; - map.insert({prebuf, "hello"}); - map.insert({postbuf, "world"}); - assert(map.size() == 2); - - auto preit = map.find(prebuf); - assert(preit != map.end()); - assert((*preit).second.compare("hello") == 0); - //if (preit != map.end()) { - // RNS::log(std::string("found prebuf: ") + (*preit).second); - //} - - auto postit = map.find(postbuf); - assert(postit != map.end()); - assert((*postit).second.compare("world") == 0); - //if (postit != map.end()) { - // RNS::log(std::string("found postbuf: ") + (*postit).second); - //} - - const uint8_t newstr[] = "World"; - RNS::Bytes newbuf(newstr, 5); - assert(newbuf.size() == 5); - assert(memcmp(newbuf.data(), "World", newbuf.size()) == 0); - auto newit = map.find(newbuf); - assert(newit != map.end()); - assert((*newit).second.compare("world") == 0); - //if (newit != map.end()) { - // RNS::log(std::string("found newbuf: ") + (*newit).second); - //} - - std::string str = map["World"]; - assert(str.size() == 5); - assert(str.compare("world") == 0); -} - -void testBytes() { - - RNS::Bytes bytes; - assert(!bytes); - assert(bytes.size() == 0); - assert(bytes.empty() == true); - assert(bytes.data() == nullptr); - - const uint8_t prestr[] = "Hello"; - const uint8_t poststr[] = " World"; - - RNS::Bytes prebuf(prestr, 5); - assert(prebuf); - assert(prebuf.size() == 5); - assert(memcmp(prebuf.data(), "Hello", prebuf.size()) == 0); - assert(!(bytes == prebuf)); - assert(bytes != prebuf); - assert(bytes < prebuf); - - RNS::Bytes postbuf(poststr, 6); - assert(postbuf); - assert(postbuf.size() == 6); - assert(memcmp(postbuf.data(), " World", postbuf.size()) == 0); - assert(!(postbuf == bytes)); - assert(postbuf != bytes); - assert(postbuf > bytes); - - assert(!(prebuf == postbuf)); - assert(prebuf != postbuf); - - //if (prebuf == postbuf) { - // RNS::log("bytess are the same"); - //} - //else { - // RNS::log("bytess are different"); - //} - - bytes += prebuf + postbuf; - assert(bytes.size() == 11); - assert(memcmp(bytes.data(), "Hello World", bytes.size()) == 0); - //RNS::log("assign bytes: " + bytes.toString()); - //RNS::log("assign prebuf: " + prebuf.toString()); - //RNS::log("assign postbuf: " + postbuf.toString()); - - bytes = "Foo"; - assert(bytes.size() == 3); - assert(memcmp(bytes.data(), "Foo", bytes.size()) == 0); - - bytes = prebuf + postbuf; - assert(bytes.size() == 11); - assert(memcmp(bytes.data(), "Hello World", bytes.size()) == 0); - - // stream into empty bytes - { - RNS::Bytes strmbuf; - strmbuf << prebuf << postbuf; - //RNS::extreme("stream strmbuf: " + strmbuf.toString()); - //RNS::extreme("stream prebuf: " + prebuf.toString()); - //RNS::extreme("stream postbuf: " + postbuf.toString()); - assert(strmbuf.size() == 11); - assert(memcmp(strmbuf.data(), "Hello World", strmbuf.size()) == 0); - assert(prebuf.size() == 5); - assert(memcmp(prebuf.data(), "Hello", prebuf.size()) == 0); - assert(postbuf.size() == 6); - assert(memcmp(postbuf.data(), " World", postbuf.size()) == 0); - } - - // stream into populated bytes - { - RNS::Bytes strmbuf("Stream "); - assert(strmbuf); - assert(strmbuf.size() == 7); - assert(memcmp(strmbuf.data(), "Stream ", strmbuf.size()) == 0); - - strmbuf << prebuf << postbuf; - //RNS::extreme("stream strmbuf: " + strmbuf.toString()); - //RNS::extreme("stream prebuf: " + prebuf.toString()); - //RNS::extreme("stream postbuf: " + postbuf.toString()); - assert(strmbuf.size() == 18); - assert(memcmp(strmbuf.data(), "Stream Hello World", strmbuf.size()) == 0); - assert(prebuf.size() == 5); - assert(memcmp(prebuf.data(), "Hello", prebuf.size()) == 0); - assert(postbuf.size() == 6); - assert(memcmp(postbuf.data(), " World", postbuf.size()) == 0); - } - - // stream with assignment - // (this is a known and correct but perhaps unexpected and non-intuitive side-effect of assignment with stream) - { - RNS::Bytes strmbuf = prebuf << postbuf; - //RNS::extreme("stream strmbuf: " + strmbuf.toString()); - //RNS::extreme("stream prebuf: " + prebuf.toString()); - //RNS::extreme("stream postbuf: " + postbuf.toString()); - assert(strmbuf.size() == 11); - assert(memcmp(strmbuf.data(), "Hello World", strmbuf.size()) == 0); - assert(prebuf.size() == 11); - assert(memcmp(prebuf.data(), "Hello World", prebuf.size()) == 0); - assert(postbuf.size() == 6); - assert(memcmp(postbuf.data(), " World", postbuf.size()) == 0); - } - - { - RNS::Bytes nonebuf = nullptr; - assert(!nonebuf); - assert(nonebuf.size() == 0); - assert(nonebuf.data() == nullptr); - } - -} - -void testCowBytes() { - - RNS::Bytes bytes1("1"); - assert(bytes1.size() == 1); - assert(memcmp(bytes1.data(), "1", bytes1.size()) == 0); - - RNS::Bytes bytes2(bytes1); - assert(bytes2.size() == 1); - assert(memcmp(bytes2.data(), "1", bytes2.size()) == 0); - assert(bytes2.data() == bytes1.data()); - - RNS::Bytes bytes3(bytes2); - assert(bytes3.size() == 1); - assert(memcmp(bytes3.data(), "1", bytes3.size()) == 0); - assert(bytes3.data() == bytes2.data()); - - //RNS::log("pre bytes1 ptr: " + std::to_string((uint32_t)bytes1.data()) + " data: " + bytes1.toString()); - //RNS::log("pre bytes2 ptr: " + std::to_string((uint32_t)bytes2.data()) + " data: " + bytes2.toString()); - //RNS::log("pre bytes3 ptr: " + std::to_string((uint32_t)bytes3.data()) + " data: " + bytes3.toString()); - - //bytes1.append("mississippi"); - //assert(bytes1.size() == 12); - //assert(memcmp(bytes1.data(), "1mississippi", bytes1.size()) == 0); - //assert(bytes1.data() != bytes2.data()); - - bytes2.append("mississippi"); - assert(bytes2.size() == 12); - assert(memcmp(bytes2.data(), "1mississippi", bytes2.size()) == 0); - assert(bytes2.data() != bytes1.data()); - - bytes3.assign("mississippi"); - assert(bytes3.size() == 11); - assert(memcmp(bytes3.data(), "mississippi", bytes3.size()) == 0); - assert(bytes3.data() != bytes2.data()); - - //RNS::log("post bytes1 ptr: " + std::to_string((uint32_t)bytes1.data()) + " data: " + bytes1.toString()); - //RNS::log("post bytes2 ptr: " + std::to_string((uint32_t)bytes2.data()) + " data: " + bytes2.toString()); - //RNS::log("post bytes3 ptr: " + std::to_string((uint32_t)bytes3.data()) + " data: " + bytes3.toString()); -} - -void testObjects() { - - RNS::Reticulum reticulum_default; - assert(reticulum_default); - - RNS::Reticulum reticulum_none(RNS::Reticulum::NONE); - assert(!reticulum_none); - - RNS::Reticulum reticulum_default_copy(reticulum_default); - assert(reticulum_default_copy); - - RNS::Reticulum reticulum_none_copy(reticulum_none); - assert(!reticulum_none_copy); - -} - -void testBytesConversion() { - - { - RNS::Bytes bytes("Hello World"); - std::string hex = bytes.toHex(); - RNS::extreme("text: \"" + bytes.toString() + "\" upper hex: \"" + hex + "\""); - assert(hex.length() == 22); - assert(hex.compare("48656C6C6F20576F726C64") == 0); - } - { - RNS::Bytes bytes("Hello World"); - std::string hex = bytes.toHex(false); - RNS::extreme("text: \"" + bytes.toString() + "\" lower hex: \"" + hex + "\""); - assert(hex.length() == 22); - assert(hex.compare("48656c6c6f20576f726c64") == 0); - } - { - std::string hex("48656C6C6F20576F726C64"); - RNS::Bytes bytes; - bytes.assignHex(hex.c_str()); - std::string text = bytes.toString(); - RNS::extreme("hex: \"" + hex + "\" text: \"" + text + "\""); - assert(text.length() == 11); - assert(text.compare("Hello World") == 0); - } - { - std::string hex("48656c6c6f20576f726c64"); - RNS::Bytes bytes; - bytes.assignHex(hex.c_str()); - std::string text = bytes.toString(); - RNS::extreme("hex: \"" + hex + "\" text: \"" + text + "\""); - assert(text.length() == 11); - assert(text.compare("Hello World") == 0); - - bytes.assignHex(hex.c_str()); - text = bytes.toString(); - RNS::extreme("hex: \"" + hex + "\" text: \"" + text + "\""); - assert(text.length() == 11); - assert(text.compare("Hello World") == 0); - - bytes.appendHex(hex.c_str()); - text = bytes.toString(); - RNS::extreme("hex: \"" + hex + "\" text: \"" + text + "\""); - assert(text.length() == 22); - assert(text.compare("Hello WorldHello World") == 0); - } - -} - - -/* -void announceLoop(RNS::Destination &destination_1, RNS::Destination &destination_2) { - // Let the user know that everything is ready - RNS::log("Announce example running, hit enter to manually send an announce (Ctrl-C to quit)"); - - // We enter a loop that runs until the users exits. - // If the user hits enter, we will announce our server - // destination on the network, which will let clients - // know how to create messages directed towards it. - //while (true) { - //zentered = input(); - RNS::log("Sending announce..."); - - // Randomly select a fruit - //const char* fruit = fruits[rand() % sizeof(fruits)]; - const char* fruit = fruits[rand() % 7]; - //RNS::log(fruit); - RNS::log(std::string("fruit: ") + fruit); - - // Send the announce including the app data - if (destination_1) { - //destination_1.announce(RNS::bytesFromString(fruit)); - // CBA TEST path - destination_1.announce(RNS::bytesFromString(fruit), true, nullptr, RNS::bytesFromString("test_tag")); - //zRNS::log(std::string("Sent announce from ") + RNS::prettyhexrep(destination_1->_hash) +" ("+ (const char*)destination_1->_name + ")"); - } - - // Randomly select a noble gas - //const char* noble_gas = noble_gases[rand() % sizeof(noble_gas)]; - const char* noble_gas = noble_gases[rand() % 7]; - //RNS::log(noble_gas); - RNS::log(std::string("noble_gas: ") + noble_gas); - - // Send the announce including the app data - if (destination_2) { - destination_2.announce(RNS::bytesFromString(noble_gas)); - //zRNS::log(std::string("Sent announce from ") + RNS::prettyhexrep(destination_2->_hash) + " (" + destination_2->_name + ")"); - } - -#ifndef NATIVE - delay(1000); -#else - usleep(1000000); -#endif - //} -} - -// This initialisation is executed when the program is started -void program_setup() { - - // We must first initialise Reticulum - RNS::Reticulum reticulum; - - // Randomly create a new identity for our example - RNS::Identity identity; - - // Using the identity we just created, we create two destinations - // in the "example_utilities.announcesample" application space. - // - // Destinations are endpoints in Reticulum, that can be addressed - // and communicated with. Destinations can also announce their - // existence, which will let the network know they are reachable - // and autoomatically create paths to them, from anywhere else - // in the network. - RNS::Destination destination_1(identity, RNS::Destination::IN, RNS::Destination::SINGLE, APP_NAME, "announcesample.fruits"); - // CBA TEST no identity - //RNS::Destination destination_1(RNS::Identity::NONE, RNS::Destination::IN, RNS::Destination::SINGLE, APP_NAME, "announcesample.fruits"); - - //RNS::Destination *destination_2(identity, RNS::Destination::IN, RNS::Destination::SINGLE, APP_NAME, "announcesample.noble_gases"); - RNS::Destination destination_2(RNS::Destination::NONE); - - // We configure the destinations to automatically prove all - // packets adressed to it. By doing this, RNS will automatically - // generate a proof for each incoming packet and transmit it - // back to the sender of that packet. This will let anyone that - // tries to communicate with the destination know whether their - // communication was received correctly. - //zdestination_1->set_proof_strategy(RNS::Destination::PROVE_ALL); - //zdestination_2->set_proof_strategy(RNS::Destination::PROVE_ALL); - - // We create an announce handler and configure it to only ask for - // announces from "example_utilities.announcesample.fruits". - // Try changing the filter and see what happens. - //zannounce_handler = ExampleAnnounceHandler( - //z aspect_filter="example_utilities.announcesample.fruits"; - //z) - - // We register the announce handler with Reticulum - //zRNS::Transport.register_announce_handler(announce_handler); - - // Everything's ready! - // Let's hand over control to the announce loop - announceLoop(destination_1, destination_2); -} -*/ - -#ifndef NATIVE void setup() { +#ifndef NATIVE Serial.begin(115200); Serial.print("Hello from T-Beam on PlatformIO!\n"); +#endif + +#ifndef NDEBUG + //RNS::loglevel(RNS::LOG_WARNING); + RNS::loglevel(RNS::LOG_EXTREME); + //test(); + testCrypto(); + return; +#endif //std::stringstream test; // !!! just adding this single stringstream alone (not even using it) adds a whopping 17.1% !!! @@ -415,42 +66,35 @@ void setup() { RNS::Destination destination(identity, RNS::Destination::IN, RNS::Destination::SINGLE, "test", "context"); // 23.0% (+0.4%) - destination.announce(RNS::bytesFromString("fruit"), true, nullptr, RNS::bytesFromString("test_tag")); + //destination.announce(RNS::bytesFromString(fruits[rand() % 7])); + // test path + destination.announce(RNS::bytesFromString(fruits[rand() % 7]), true, nullptr, RNS::bytesFromString("test_tag")); // 23.9% (+0.8%) -#ifndef NDEBUG - // begin with logging turned down for unit tests - RNS::loglevel(RNS::LOG_WARNING); - //RNS::loglevel(RNS::LOG_EXTREME); + //zdestination.set_proof_strategy(RNS::Destination::PROVE_ALL); - testMap(); - testBytes(); - testCowBytes(); - testObjects(); - testBytesConversion(); + //zannounce_handler = ExampleAnnounceHandler( + //z aspect_filter="example_utilities.announcesample.fruits"; + //z) - // 24.8% (+0.9%) -#endif - - // increase logging for functional tests - RNS::loglevel(RNS::LOG_EXTREME); - - //program_setup(); + //zRNS::Transport.register_announce_handler(announce_handler); +#ifndef NATIVE Serial.print("Goodbye from T-Beam on PlatformIO!\n"); +#endif } void loop() { } -#else - -int main(int argc, char **argv) { +int main(void) { printf("Hello from Native on PlatformIO!\n"); - program_setup(); + setup(); + + //while (true) { + // loop(); + //} printf("Goodbye from Native on PlatformIO!\n"); } - -#endif diff --git a/test/test.cpp b/test/test.cpp deleted file mode 100644 index 7380eaa..0000000 --- a/test/test.cpp +++ /dev/null @@ -1,157 +0,0 @@ -#include "Reticulum.h" -#include "Identity.h" -#include "Destination.h" - -#ifndef NATIVE -#include -#endif -#include -#include - -#include - -// Let's define an app name. We'll use this for all -// destinations we create. Since this basic example -// is part of a range of example utilities, we'll put -// them all within the app namespace "example_utilities" -const char* APP_NAME = "example_utilities"; - -// We initialise two lists of strings to use as app_data -const char* fruits[] = {"Peach", "Quince", "Date", "Tangerine", "Pomelo", "Carambola", "Grape"}; -const char* noble_gases[] = {"Helium", "Neon", "Argon", "Krypton", "Xenon", "Radon", "Oganesson"}; - -void announceLoop(RNS::Destination* destination_1, RNS::Destination* destination_2) { - // Let the user know that everything is ready - RNS::log("Announce example running, hit enter to manually send an announce (Ctrl-C to quit)"); - - // We enter a loop that runs until the users exits. - // If the user hits enter, we will announce our server - // destination on the network, which will let clients - // know how to create messages directed towards it. - while (true) { - //zentered = input(); -#ifndef NATIVE - delay(1000); -#else - usleep(1000); -#endif - RNS::log("Sending announce..."); - - // Randomly select a fruit - //const char* fruit = fruits[rand() % sizeof(fruits)]; - const char* fruit = fruits[rand() % 7]; - RNS::log(fruit); - //RNS::log(String("fruit: ") + fruit); - - // Send the announce including the app data -/* - destination_1->announce(app_data=fruit.encode("utf-8")); - RNS::log( - "Sent announce from "+ - RNS.prettyhexrep(destination_1.hash)+ - " ("+destination_1.name+")" - ); -*/ - - // Randomly select a noble gas - //const char* noble_gas = noble_gases[rand() % sizeof(noble_gas)]; - const char* noble_gas = noble_gases[rand() % 7]; - RNS::log(noble_gas); - //RNS::log(String("noble_gas: ") + noble_gas); - - // Send the announce including the app data -/* - destination_2->announce(app_data=noble_gas.encode("utf-8")); - RNS::log( - "Sent announce from "+ - RNS.prettyhexrep(destination_2.hash)+ - " ("+destination_2.name+")" - ); -*/ - } -} - -// This initialisation is executed when the program is started -void program_setup() { - // We must first initialise Reticulum - RNS::Reticulum* reticulum = new RNS::Reticulum(); - - // Randomly create a new identity for our example - RNS::Identity* identity = new RNS::Identity(); - - // Using the identity we just created, we create two destinations - // in the "example_utilities.announcesample" application space. - // - // Destinations are endpoints in Reticulum, that can be addressed - // and communicated with. Destinations can also announce their - // existence, which will let the network know they are reachable - // and autoomatically create paths to them, from anywhere else - // in the network. - RNS::Destination* destination_1 = new RNS::Destination( - identity, - RNS::Destination::IN, - RNS::Destination::SINGLE, - APP_NAME, - //z"announcesample", - //z"fruits" - nullptr - ); - - RNS::Destination* destination_2 = new RNS::Destination( - identity, - RNS::Destination::IN, - RNS::Destination::SINGLE, - APP_NAME, - //z"announcesample", - //z"noble_gases" - nullptr - ); - - // We configure the destinations to automatically prove all - // packets adressed to it. By doing this, RNS will automatically - // generate a proof for each incoming packet and transmit it - // back to the sender of that packet. This will let anyone that - // tries to communicate with the destination know whether their - // communication was received correctly. - //zdestination_1->set_proof_strategy(RNS::Destination::PROVE_ALL); - //zdestination_2->set_proof_strategy(RNS::Destination::PROVE_ALL); - - // We create an announce handler and configure it to only ask for - // announces from "example_utilities.announcesample.fruits". - // Try changing the filter and see what happens. - //zannounce_handler = ExampleAnnounceHandler( - //z aspect_filter="example_utilities.announcesample.fruits"; - //z) - - // We register the announce handler with Reticulum - //zRNS::Transport.register_announce_handler(announce_handler); - - // Everything's ready! - // Let's hand over control to the announce loop - announceLoop(destination_1, destination_2); -} - - -#ifndef NATIVE - -void setup() { - - Serial.begin(115200); - RNS::log("Hello T-Beam from PlatformIO!"); - - program_setup(); -} - -void loop() { -} - -#else - -int main(int argc, char **argv) { - RNS::log("Hello Native from PlatformIO!"); - UNITY_BEGIN(); - RUN_TEST(program_setup); - UNITY_END(); -} - -#endif