Wiselib
|
00001 // 00002 // File: dfsclustering.h 00003 // Author: mpairakt 00004 // 00005 // Created on September 25, 2009, 4:04 PM 00006 // 00007 00008 #ifndef _SECUREDFSCLUSTERING_H 00009 #define _SECUREDFSCLUSTERING_H 00010 00011 #include "util/delegates/delegate.hpp" 00012 #include "securedfsclusteringmessage.h" 00013 #include "algorithms/crypto/ecc.h" 00014 #include <stack> 00015 #include <cstdlib> 00016 #include <iostream> 00017 00018 namespace wiselib { 00019 00020 class ECGDH { 00021 public: 00022 static PubKey generate_random_ECpoint() { 00023 PubKey ret; 00024 ECC::p_clear(&(ret.W)); 00025 ECC::gen_public_key(generate_random_ECfactor().s, &(ret.W)); 00026 return ret; 00027 } 00028 static PrivKey generate_random_ECfactor() { 00029 uint8_t a[NUMWORDS]; 00030 ECC::b_clear(a); 00031 uint8_t d=1, b=rand()%256; 00032 for (uint8_t i = NUMWORDS/2; i < NUMWORDS; i++) 00033 { 00034 d = (d*i) + (234 - b); 00035 a[i] = (uint8_t) d; //rand()%256; 00036 } 00037 ECC::b_mod(a, params.r, NUMWORDS/2); 00038 PrivKey ret; 00039 memcpy(ret.s, a, NUMWORDS); 00040 return ret; 00041 } 00042 static PubKey multiply(PrivKey k, PubKey P) {// return 0; } // Point * gen_shared_secret(uint8_t * a,Point * P0, Point * P1) 00043 PubKey ret; 00044 ECC::p_clear(&(ret.W)); 00045 ECC::gen_shared_secret(k.s, &(P.W), &(ret.W)); 00046 return ret; 00047 } 00048 static PubKey divide(PrivKey k, PubKey P) { 00049 PrivKey k_; 00050 ECC::b_clear(k_.s); 00051 ECC::f_inv(k.s, k_.s); 00052 ; 00053 return multiply(k_, P); 00054 } 00055 static PubKey encrypt(PubKey P) { 00056 PubKey ret, G; 00057 G.W=params.G; 00058 ECC::p_clear(&(ret.W)); 00059 ECC::c_add(&(G.W), &(P.W), &(ret.W)); 00060 return ret; 00061 } 00062 static PubKey decrypt(PubKey P) { 00063 PubKey ret, G; 00064 G.W=params.G; 00065 ECC::p_clear(&(ret.W)); 00066 PubKey temp; 00067 ECC::p_clear(&(temp.W)); 00068 ECC::f_add(G.W.x.val, G.W.y.val, temp.W.y.val); 00069 memcpy((void*) temp.W.x.val, (void*) G.W.x.val, NUMWORDS); 00070 ECC::c_add(&temp.W, &P.W, &ret.W); 00071 return ret; 00072 } 00073 }; 00081 template<typename OsModel_P, 00082 typename Radio_P = typename OsModel_P::Radio, 00083 typename Timer_P = typename OsModel_P::Timer> 00084 class SecureDfsClustering { 00085 00086 public: 00087 00088 typedef int cluster_id_t; 00089 typedef int cluster_level_t; //quite useless within current scheme, supported for compatibility issues 00090 typedef OsModel_P OsModel; 00091 typedef Radio_P Radio; 00092 typedef Timer_P Timer; 00093 00094 typedef SecureDfsClustering<OsModel_P, Radio_P> self_t; 00095 00096 typedef typename Radio::node_id_t node_id_t; 00097 typedef typename Radio::size_t size_t; 00098 typedef typename Radio::block_data_t block_data_t; 00099 00100 typedef SecureDFSMessage<OsModel, Radio> Message; 00101 00102 typedef delegate1<void, int> cluster_delegate_t; 00103 00104 //quite useless within current scheme, supported for compatibility issues 00105 enum EventIds { 00106 CLUSTER_HEAD_CHANGED = 0, 00107 NODE_JOINED = 1, 00108 NODE_LEFT = 2 00109 }; 00110 00111 //quite useless within current scheme, supported for compatibility issues 00112 enum ClusterIds { 00113 UNKNOWN_CLUSTER_HEAD = 0 00114 }; 00115 00116 public: 00117 void enable(); 00118 void disable(); 00119 00120 inline cluster_id_t cluster_id( cluster_level_t ) { return sid_; } 00121 inline cluster_level_t cluster_level() { return 0; } 00122 00123 template<class T, void (T::*TMethod)(int)> 00124 inline int reg_changed_callback( T *obj_pnt ) { 00125 state_changed_callback_=cluster_delegate_t::from_method<T, TMethod>( obj_pnt ); 00126 } 00127 inline void unreg_changed_callback( int idx ) { 00128 state_changed_callback_=cluster_delegate_t(); 00129 } 00130 00131 inline void set_cluster_head( bool cluster_head) { cluster_head_=cluster_head; } 00132 inline bool cluster_head() { return cluster_head_; } 00133 00134 inline node_id_t parent() { return parent_; } 00135 00136 inline int *group_key_x() { 00137 int *ret=new int[21]; 00138 for(int i=0; i<21; i++) { 00139 ret[i]=group_key_.W.x.val[i+21]; 00140 } 00141 return ret; 00142 } 00143 00144 inline int *group_key_y() { 00145 int *ret=new int[21]; 00146 for(int i=0; i<21; i++) { 00147 ret[i]=group_key_.W.y.val[i+21]; 00148 } 00149 return ret; 00150 } 00151 00154 SecureDfsClustering(): 00155 cluster_head_(false), 00156 sid_(-1), 00157 time_slice_(2001), 00158 received_ck_send(false) 00159 {}; 00160 ~SecureDfsClustering() {}; 00162 00163 protected: 00164 void discover_neighbors(); 00165 void timer_expired(void*); 00166 void receive(node_id_t from, size_t len, block_data_t* data); 00167 00168 private: 00169 Radio& radio() 00170 { return *radio_; } 00171 00172 Timer& timer() 00173 { return *timer_; } 00174 00175 Radio * radio_; 00176 Timer * timer_; 00177 00178 bool cluster_head_, received_ck_send; 00179 cluster_id_t sid_; 00180 int callback_id_; 00181 cluster_delegate_t state_changed_callback_; 00182 std::stack<node_id_t> neighbors_; 00183 node_id_t parent_; 00184 PrivKey private_key_; 00185 PubKey group_key_, parent_key_; 00186 int time_slice_; 00187 }; 00188 00189 template<typename OsModel_P, 00190 typename Radio_P, 00191 typename Timer_P> 00192 void 00193 SecureDfsClustering<OsModel_P, Radio_P, Timer_P>:: 00194 enable() { 00195 ECC::init(); 00196 radio().enable_radio(); 00197 callback_id_ = radio().template reg_recv_callback<self_t, &self_t::receive>(this ); 00198 if(cluster_head_) { 00199 //I am cluster_head, set SID_ to id and discover_neighbors 00200 sid_=parent_=radio().id(); 00201 private_key_=ECGDH::generate_random_ECfactor(); 00202 group_key_=ECGDH::generate_random_ECpoint(); 00203 discover_neighbors(); 00204 std::cout<<"Node "<<radio().id()<<" ( "<<sid_<<" ) generated group key : "; 00205 int *x=group_key_x(); 00206 int *y=group_key_y(); 00207 for(int i=0; i<7; i++) { 00208 printf("%x/%x ", x[i], y[i]); 00209 } 00210 std::cout<<std::endl; 00211 } else { 00212 private_key_=ECGDH::generate_random_ECfactor(); 00213 } 00214 } 00215 00216 template<typename OsModel_P, 00217 typename Radio_P, 00218 typename Timer_P> 00219 void 00220 SecureDfsClustering<OsModel_P, Radio_P, Timer_P>:: 00221 discover_neighbors( void ) { 00222 Message omsg; 00223 omsg.set_msg_id(Message::NEIGHBOR_DISCOVERY); 00224 while(!neighbors_.empty()) neighbors_.pop(); 00225 radio().send(radio().BROADCAST_ADDRESS, 1, (block_data_t*) &omsg); 00226 timer().template set_timer<self_t, &self_t::timer_expired>(time_slice_, this, (void*) 0); 00227 } 00228 00229 template<typename OsModel_P, 00230 typename Radio_P, 00231 typename Timer_P> 00232 void 00233 SecureDfsClustering<OsModel_P, Radio_P, Timer_P>:: 00234 timer_expired( void* data ) { 00235 if (neighbors_.empty()) { 00236 if(!cluster_head_) { 00237 Message msg; 00238 msg.set_msg_id(Message::RESUME); 00239 msg.set_sid(sid_); 00240 PubKey temp; 00241 ECC::p_clear(&temp.W); 00242 temp=ECGDH::encrypt(group_key_); 00243 msg.set_key(&temp); 00244 00245 radio().send(parent_, msg.buffer_size(), (block_data_t*) &msg); 00246 } else { 00247 Message msg; 00248 msg.set_msg_id(Message::CK_SEND); 00249 msg.set_sid(sid_); 00250 PubKey temp; 00251 ECC::p_clear(&temp.W); 00252 temp=ECGDH::encrypt(group_key_); 00253 msg.set_key(&temp); 00254 received_ck_send=true; 00255 radio().send(radio().BROADCAST_ADDRESS, msg.buffer_size(),(block_data_t*) &msg); 00256 } 00257 } else { 00258 node_id_t dest=neighbors_.top(); 00259 neighbors_.pop(); 00260 Message msg; 00261 msg.set_msg_id(Message::JOIN_REQUEST); 00262 msg.set_sid(sid_); 00263 msg.set_key(&group_key_); 00264 radio().send(dest, msg.buffer_size(), (block_data_t*) &msg); 00265 } 00266 00267 } 00268 00269 template<typename OsModel_P, 00270 typename Radio_P, 00271 typename Timer_P> 00272 void 00273 SecureDfsClustering<OsModel_P, Radio_P, Timer_P>:: 00274 receive(node_id_t from, size_t len, block_data_t* data) { 00275 00276 if ( from == radio().id() ) return; 00277 00278 Message *msg=(Message*) data; 00279 if( msg->msg_id()==Message::NEIGHBOR_DISCOVERY ) { 00280 if(sid_==-1) { 00281 Message omsg; 00282 omsg.set_msg_id(Message::NEIGHBOR_REPLY ); 00283 radio().send(from, 1, (block_data_t*) &omsg); 00284 } 00285 } 00286 00287 else if( msg->msg_id() == Message::NEIGHBOR_REPLY ) { 00288 neighbors_.push(from); 00289 } 00290 00291 else if( msg->msg_id() == Message::JOIN_REQUEST ) { 00292 if (sid_==-1) { 00293 parent_=from; 00294 sid_=msg->sid(); 00295 state_changed_callback_(NODE_JOINED); 00296 memcpy(&parent_key_, msg->key(), 2*NUMWORDS); 00297 group_key_=ECGDH::multiply(private_key_, parent_key_); 00298 discover_neighbors(); 00299 std::cout<<"Node "<<radio().id()<<" ( "<<sid_<<" ) (just joined) group key is: "; 00300 int *x=group_key_x(); 00301 int *y=group_key_y(); 00302 for(int i=0; i<7; i++) { 00303 printf("%x/%x ", x[i], y[i]); 00304 } 00305 std::cout<<std::endl; 00306 } else { 00307 Message omsg; 00308 std::cout<<"sent join_deny"<<msg->sid()<<","<<sid_<<std::endl; 00309 omsg.set_msg_id(Message::JOIN_DENY); 00310 radio().send(from, 1,(block_data_t*) &omsg); 00311 } 00312 } 00313 00314 else if( msg->msg_id() == Message::JOIN_DENY ) { 00315 discover_neighbors(); 00316 } 00317 00318 else if( msg->msg_id() == Message::RESUME ) { 00319 group_key_=ECGDH::decrypt(*msg->key()); 00320 discover_neighbors(); 00321 std::cout<<"Node "<<radio().id()<<" ( "<<sid_<<" ) (just received resume) group key is: "; 00322 int *x=group_key_x(); 00323 int *y=group_key_y(); 00324 for(int i=0; i<7; i++) { 00325 printf("%x/%x ", x[i], y[i]); 00326 } 00327 std::cout<<std::endl; 00328 } 00329 00330 else if( (msg->msg_id() == Message::CK_SEND) && (msg->sid()==sid_) ) { 00331 group_key_=ECGDH::decrypt(*msg->key()); 00332 if(!received_ck_send) { 00333 received_ck_send=true; 00334 radio().send(radio().BROADCAST_ADDRESS, msg->buffer_size(),(block_data_t*) msg); 00335 std::cout<<"Node "<<radio().id()<<" ( "<<sid_<<" ) (just received ck_send) group key is: "; 00336 int *x=group_key_x(); 00337 int *y=group_key_y(); 00338 for(int i=0; i<7; i++) { 00339 printf("%x/%x ", x[i], y[i]); 00340 } 00341 std::cout<<std::endl; 00342 } 00343 } 00344 00345 00346 } 00347 } 00348 00349 00350 #endif /* _SECUREDFSCLUSTERING_H */ 00351