rewrote network addressess to base on boost::asio
[anytun.git] / src / mpi.cpp
blob0a240fda9cc41882711451086d794ce55566b1b7
1 /*
2 * anytun
4 * The secure anycast tunneling protocol (satp) defines a protocol used
5 * for communication between any combination of unicast and anycast
6 * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel
7 * mode and allows tunneling of every ETHER TYPE protocol (e.g.
8 * ethernet, ip, arp ...). satp directly includes cryptography and
9 * message authentication based on the methodes used by SRTP. It is
10 * intended to deliver a generic, scaleable and secure solution for
11 * tunneling and relaying of packets of any protocol.
14 * Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl,
15 * Christian Pointner <satp@wirdorange.org>
17 * This file is part of Anytun.
19 * Anytun is free software: you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License version 3 as
21 * published by the Free Software Foundation.
23 * Anytun is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
28 * You should have received a copy of the GNU General Public License
29 * along with anytun. If not, see <http://www.gnu.org/licenses/>.
32 #include "mpi.h"
34 #include "datatypes.h"
35 #include "cipher.h"
37 #include <stdexcept>
38 #include <gcrypt.h>
40 #include <iostream>
41 #include <cstring>
43 Mpi::Mpi() : val_(NULL)
45 val_ = gcry_mpi_set_ui(NULL, 0);
46 if(!val_)
47 throw std::bad_alloc();
50 Mpi::Mpi(u_int8_t length) : val_(NULL)
52 val_ = gcry_mpi_new(length);
53 if(!val_)
54 throw std::bad_alloc();
57 Mpi::Mpi(const Mpi &src) : val_(NULL)
59 val_ = gcry_mpi_copy(src.val_);
60 if(!val_)
61 throw std::bad_alloc();
64 Mpi::Mpi(const u_int8_t* src, u_int32_t len) : val_(NULL)
66 u_int8_t* src_cpy = new u_int8_t[len+1];
67 if(!src_cpy)
68 throw std::bad_alloc();
70 u_int8_t* buf = src_cpy;
71 u_int32_t buf_len = len;
72 if(src[0] & 0x80) // this would be a negative number, scan can't handle this :(
74 src_cpy[0] = 0;
75 buf++;
76 buf_len++;
78 std::memcpy(buf, src, len);
80 gcry_mpi_scan( &val_, GCRYMPI_FMT_STD, src_cpy, buf_len, NULL );
81 delete[] src_cpy;
82 if(!val_)
83 throw std::bad_alloc();
86 Mpi::~Mpi()
88 gcry_mpi_release( val_ );
92 void Mpi::operator=(const Mpi &src)
94 gcry_mpi_release( val_ );
95 val_ = gcry_mpi_copy(src.val_);
96 if(!val_)
97 throw std::bad_alloc();
100 void Mpi::operator=(const u_int32_t src)
102 gcry_mpi_release( val_ );
103 val_ = gcry_mpi_set_ui(NULL, src);
104 if(!val_)
105 throw std::bad_alloc();
108 Mpi Mpi::operator+(const Mpi &b) const
110 Mpi res;
111 gcry_mpi_add(res.val_, val_, b.val_);
112 return res;
115 Mpi Mpi::operator+(const u_int32_t &b) const
117 Mpi res;
118 gcry_mpi_add_ui(res.val_, val_, b);
119 return res;
122 Mpi Mpi::operator*(const u_int32_t n) const
124 Mpi res;
125 gcry_mpi_mul_ui(res.val_, val_, n);
126 return res;
129 Mpi Mpi::operator/(const Mpi &b) const
131 Mpi res;
132 gcry_mpi_div(res.val_, NULL, val_, b.val_, 0);
133 return res;
136 //TODO: this is outstandingly ugly!!!!!!!!
137 Mpi Mpi::operator^(const Mpi &b) const
139 u_int32_t a_len = gcry_mpi_get_nbits(val_);
140 u_int32_t b_len = gcry_mpi_get_nbits(b.val_);
142 Mpi res = (a_len >= b_len) ? Mpi(*this) : Mpi(b);
144 for(u_int32_t i=0; i<a_len && i<b_len; i++) {
145 if(gcry_mpi_test_bit(val_, i) ^ gcry_mpi_test_bit(b.val_, i))
146 gcry_mpi_set_bit(res.val_, i);
147 else
148 gcry_mpi_clear_bit(res.val_, i);
150 return res;
153 Mpi Mpi::mul2exp(u_int32_t e) const
155 Mpi res;
156 gcry_mpi_mul_2exp( res.val_, val_, e );
157 return res;
160 //TODO: problem, seems as gcry_mpi_(a)print doesn't work for mpi values of '0'
161 u_int8_t* Mpi::getNewBuf(size_t* written) const
163 u_int8_t* res_cpy;
164 gcry_mpi_aprint( GCRYMPI_FMT_STD, &res_cpy, written, val_ );
165 if(!res_cpy)
166 throw std::bad_alloc();
168 u_int8_t* buf = res_cpy;
169 if(*written > 1 && ! (res_cpy[0])) // positive number with highestBit set
171 buf++;
172 (*written)--;
175 u_int8_t* res = new u_int8_t[*written];
176 if(!res)
177 throw std::bad_alloc();
179 std::memcpy(res, buf, *written);
181 gcry_free(res_cpy);
183 return res;
186 //TODO: why does this not work ?????
187 std::string Mpi::getHexDump() const
189 // u_int8_t *buf;
190 // u_int32_t len;
191 // gcry_mpi_aprint( GCRYMPI_FMT_HEX, &buf, &len, val_ );
192 // std::string res(buf, len);
193 // delete[] buf;
195 gcry_mpi_dump( val_ );
196 std::string res("\n");
197 return res;
200 u_int32_t Mpi::getLength() const
202 return gcry_mpi_get_nbits( val_ );