sync bug fixed
[anytun.git] / mpi.cpp
bloba2590fa31b6d2919d23f2e5e1f3cb52638228f1a
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 anytun.org <satp@wirdorange.org>
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License version 2
18 * as published by the Free Software Foundation.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program (see the file COPYING included with this
27 * distribution); if not, write to the Free Software Foundation, Inc.,
28 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 #include "mpi.h"
33 #include "datatypes.h"
34 #include "cipher.h"
36 #include <stdexcept>
37 #include <gcrypt.h>
39 #include <iostream>
41 Mpi::Mpi() : val_(NULL)
43 val_ = gcry_mpi_set_ui(NULL, 0);
44 if(!val_)
45 throw std::bad_alloc();
48 Mpi::Mpi(u_int8_t length) : val_(NULL)
50 val_ = gcry_mpi_new(length);
51 if(!val_)
52 throw std::bad_alloc();
55 Mpi::Mpi(const Mpi &src) : val_(NULL)
57 val_ = gcry_mpi_copy(src.val_);
58 if(!val_)
59 throw std::bad_alloc();
62 Mpi::Mpi(const u_int8_t* src, u_int32_t len) : val_(NULL)
64 u_int8_t* src_cpy = new u_int8_t[len+1];
65 if(!src_cpy)
66 throw std::bad_alloc();
68 u_int8_t* buf = src_cpy;
69 u_int32_t buf_len = len;
70 if(src[0] & 0x80) // this would be a negative number, scan can't handle this :(
72 src_cpy[0] = 0;
73 buf++;
74 buf_len++;
76 std::memcpy(buf, src, len);
78 gcry_mpi_scan( &val_, GCRYMPI_FMT_STD, src_cpy, buf_len, NULL );
79 delete[] src_cpy;
80 if(!val_)
81 throw std::bad_alloc();
84 Mpi::~Mpi()
86 gcry_mpi_release( val_ );
90 void Mpi::operator=(const Mpi &src)
92 gcry_mpi_release( val_ );
93 val_ = gcry_mpi_copy(src.val_);
94 if(!val_)
95 throw std::bad_alloc();
98 void Mpi::operator=(const u_int32_t src)
100 gcry_mpi_release( val_ );
101 val_ = gcry_mpi_set_ui(NULL, src);
102 if(!val_)
103 throw std::bad_alloc();
106 Mpi Mpi::operator+(const Mpi &b) const
108 Mpi res;
109 gcry_mpi_add(res.val_, val_, b.val_);
110 return res;
113 Mpi Mpi::operator+(const u_int32_t &b) const
115 Mpi res;
116 gcry_mpi_add_ui(res.val_, val_, b);
117 return res;
120 Mpi Mpi::operator*(const u_int32_t n) const
122 Mpi res;
123 gcry_mpi_mul_ui(res.val_, val_, n);
124 return res;
127 Mpi Mpi::operator/(const Mpi &b) const
129 Mpi res;
130 gcry_mpi_div(res.val_, NULL, val_, b.val_, 0);
131 return res;
134 //TODO: this is outstandingly ugly!!!!!!!!
135 Mpi Mpi::operator^(const Mpi &b) const
137 u_int32_t a_len = gcry_mpi_get_nbits(val_);
138 u_int32_t b_len = gcry_mpi_get_nbits(b.val_);
140 Mpi res = (a_len >= b_len) ? Mpi(*this) : Mpi(b);
142 for(u_int32_t i=0; i<a_len && i<b_len; i++) {
143 if(gcry_mpi_test_bit(val_, i) ^ gcry_mpi_test_bit(b.val_, i))
144 gcry_mpi_set_bit(res.val_, i);
145 else
146 gcry_mpi_clear_bit(res.val_, i);
148 return res;
151 Mpi Mpi::mul2exp(u_int32_t e) const
153 Mpi res;
154 gcry_mpi_mul_2exp( res.val_, val_, e );
155 return res;
158 //TODO: problem, seems as gcry_mpi_(a)print doesn't work for mpi values of '0'
159 u_int8_t* Mpi::getNewBuf(u_int32_t* written) const
161 u_int8_t* res_cpy;
162 gcry_mpi_aprint( GCRYMPI_FMT_STD, &res_cpy, written, val_ );
163 if(!res_cpy)
164 throw std::bad_alloc();
166 u_int8_t* buf = res_cpy;
167 if(*written > 1 && ! (res_cpy[0])) // positive number with highestBit set
169 buf++;
170 (*written)--;
173 u_int8_t* res = new u_int8_t[*written];
174 if(!res)
175 throw std::bad_alloc();
177 std::memcpy(res, buf, *written);
179 gcry_free(res_cpy);
181 return res;
184 //TODO: why does this not work ?????
185 std::string Mpi::getHexDump() const
187 // u_int8_t *buf;
188 // u_int32_t len;
189 // gcry_mpi_aprint( GCRYMPI_FMT_HEX, &buf, &len, val_ );
190 // std::string res(buf, len);
191 // delete[] buf;
193 gcry_mpi_dump( val_ );
194 std::string res("\n");
195 return res;
198 u_int32_t Mpi::getLength() const
200 return gcry_mpi_get_nbits( val_ );