Wiselib
wiselib.testing/algorithms/cluster/securedfscluster/securedfsclustering.h
Go to the documentation of this file.
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines