From 00e4eb1ef3c535967f949102bf5eae638a507572 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Thu, 23 Oct 2014 13:30:33 +0200 Subject: [PATCH] Whisper can sign messages. --- exp/main.cpp | 9 ++++++--- libwhisper/Interface.h | 8 ++++---- libwhisper/Message.cpp | 10 +++++++--- libwhisper/Message.h | 2 +- 4 files changed, 18 insertions(+), 11 deletions(-) diff --git a/exp/main.cpp b/exp/main.cpp index c1c6139a2..3af192380 100644 --- a/exp/main.cpp +++ b/exp/main.cpp @@ -105,14 +105,17 @@ int main(int argc, char** argv) /// Only interested in odd packets auto w = wh->installWatch(BuildTopicMask()("odd")); + KeyPair us = KeyPair::create(); for (int i = 0; ; ++i) { - wh->sendRaw(RLPStream().append(i * i).out(), BuildTopic(i)(i % 2 ? "odd" : "even")); + wh->post(us.sec(), RLPStream().append(i * i).out(), BuildTopic(i)(i % 2 ? "odd" : "even")); for (auto i: wh->checkWatch(w)) { - auto p = wh->envelope(i).open().payload(); - cnote << "New message:" << RLP(p).toInt(); + Message msg = wh->envelope(i).open(); + + cnote << "New message from:" << msg.from().abridged() << RLP(msg.payload()).toInt(); } + this_thread::sleep_for(chrono::seconds(1)); } return 0; } diff --git a/libwhisper/Interface.h b/libwhisper/Interface.h index 3b2ec7267..e131a3ada 100644 --- a/libwhisper/Interface.h +++ b/libwhisper/Interface.h @@ -76,10 +76,10 @@ public: virtual Envelope envelope(h256 _m) const = 0; - void sendRaw(bytes const& _payload, Topic _topic, unsigned _ttl = 50, unsigned _workToProve = 50) { inject(Message(_payload).seal(_topic, _ttl, _workToProve)); } - void sendRaw(Public _to, bytes const& _payload, Topic _topic, unsigned _ttl = 50, unsigned _workToProve = 50) { inject(Message(_payload).seal(_to, _topic, _ttl, _workToProve)); } - void sendRaw(Secret _from, bytes const& _payload, Topic _topic, unsigned _ttl = 50, unsigned _workToProve = 50) { inject(Message(_payload).seal(_from, _topic, _ttl, _workToProve)); } - void sendRaw(Secret _from, Public _to, bytes const& _payload, Topic _topic, unsigned _ttl = 50, unsigned _workToProve = 50) { inject(Message(_payload).seal(_from, _to, _topic, _ttl, _workToProve)); } + void post(bytes const& _payload, Topic _topic, unsigned _ttl = 50, unsigned _workToProve = 50) { inject(Message(_payload).seal(_topic, _ttl, _workToProve)); } + void post(Public _to, bytes const& _payload, Topic _topic, unsigned _ttl = 50, unsigned _workToProve = 50) { inject(Message(_payload).seal(_to, _topic, _ttl, _workToProve)); } + void post(Secret _from, bytes const& _payload, Topic _topic, unsigned _ttl = 50, unsigned _workToProve = 50) { inject(Message(_payload).seal(_from, _topic, _ttl, _workToProve)); } + void post(Secret _from, Public _to, bytes const& _payload, Topic _topic, unsigned _ttl = 50, unsigned _workToProve = 50) { inject(Message(_payload).seal(_from, _to, _topic, _ttl, _workToProve)); } }; struct WatshhChannel: public dev::LogChannel { static const char* name() { return "shh"; } static const int verbosity = 1; }; diff --git a/libwhisper/Message.cpp b/libwhisper/Message.cpp index 5d8466a2c..80b493076 100644 --- a/libwhisper/Message.cpp +++ b/libwhisper/Message.cpp @@ -32,7 +32,8 @@ Message::Message(Envelope const& _e, Secret const& _s) { bytes b; if (_s) - decrypt(_s, &(_e.data()), b); + if (!decrypt(_s, &(_e.data()), b)) + return; populate(_s ? b : _e.data()); m_to = KeyPair(_s).pub(); } @@ -49,9 +50,10 @@ void Message::populate(bytes const& _data) byte flags = _data[0]; if (!!(flags & ContainsSignature) && _data.size() > sizeof(Signature) + 1) // has a signature { - bytesConstRef payload = bytesConstRef(&_data).cropped(sizeof(Signature) + 1); + bytesConstRef payload = bytesConstRef(&_data).cropped(1, _data.size() - sizeof(Signature) - 1); h256 h = sha3(payload); - m_from = recover(*(Signature const*)&(_data[1]), h); + Signature const& sig = *(Signature const*)&(_data[1 + payload.size()]); + m_from = recover(sig, h); m_payload = payload.toBytes(); } else @@ -71,6 +73,8 @@ Envelope Message::seal(Secret _from, Topic const& _topic, unsigned _ttl, unsigne input.resize(1 + m_payload.size() + sizeof(Signature)); input[0] |= ContainsSignature; *(Signature*)&(input[1 + m_payload.size()]) = sign(_from, sha3(m_payload)); + // If this fails, the something is wrong with the sign-recover round-trip. + assert(recover(*(Signature*)&(input[1 + m_payload.size()]), sha3(m_payload)) == KeyPair(_from).pub()); } if (m_to) diff --git a/libwhisper/Message.h b/libwhisper/Message.h index 17ddb3f7f..fa5cc3662 100644 --- a/libwhisper/Message.h +++ b/libwhisper/Message.h @@ -84,7 +84,7 @@ private: enum /*Message Flags*/ { - ContainsSignature = 0 + ContainsSignature = 1 }; /// An (unencrypted) message, constructed from the combination of an Envelope, and, potentially,