Open-Transactions  0.93.0-ge03d287
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
OTIdentifier.cpp
Go to the documentation of this file.
1 /************************************************************
2  *
3  * OTIdentifier.cpp
4  *
5  */
6 
7 /************************************************************
8  -----BEGIN PGP SIGNED MESSAGE-----
9  Hash: SHA1
10 
11  * OPEN TRANSACTIONS
12  *
13  * Financial Cryptography and Digital Cash
14  * Library, Protocol, API, Server, CLI, GUI
15  *
16  * -- Anonymous Numbered Accounts.
17  * -- Untraceable Digital Cash.
18  * -- Triple-Signed Receipts.
19  * -- Cheques, Vouchers, Transfers, Inboxes.
20  * -- Basket Currencies, Markets, Payment Plans.
21  * -- Signed, XML, Ricardian-style Contracts.
22  * -- Scripted smart contracts.
23  *
24  * Copyright (C) 2010-2013 by "Fellow Traveler" (A pseudonym)
25  *
26  * EMAIL:
28  *
29  * BITCOIN: 1NtTPVVjDsUfDWybS4BwvHpG2pdS9RnYyQ
30  *
31  * KEY FINGERPRINT (PGP Key in license file):
32  * 9DD5 90EB 9292 4B48 0484 7910 0308 00ED F951 BB8E
33  *
34  * OFFICIAL PROJECT WIKI(s):
35  * https://github.com/FellowTraveler/Moneychanger
36  * https://github.com/FellowTraveler/Open-Transactions/wiki
37  *
38  * WEBSITE:
39  * http://www.OpenTransactions.org/
40  *
41  * Components and licensing:
42  * -- Moneychanger..A Java client GUI.....LICENSE:.....GPLv3
43  * -- otlib.........A class library.......LICENSE:...LAGPLv3
44  * -- otapi.........A client API..........LICENSE:...LAGPLv3
45  * -- opentxs/ot....Command-line client...LICENSE:...LAGPLv3
46  * -- otserver......Server Application....LICENSE:....AGPLv3
47  * Github.com/FellowTraveler/Open-Transactions/wiki/Components
48  *
49  * All of the above OT components were designed and written by
50  * Fellow Traveler, with the exception of Moneychanger, which
51  * was contracted out to Vicky C ([email protected]).
52  * The open-source community has since actively contributed.
53  *
54  * -----------------------------------------------------
55  *
56  * LICENSE:
57  * This program is free software: you can redistribute it
58  * and/or modify it under the terms of the GNU Affero
59  * General Public License as published by the Free Software
60  * Foundation, either version 3 of the License, or (at your
61  * option) any later version.
62  *
63  * ADDITIONAL PERMISSION under the GNU Affero GPL version 3
64  * section 7: (This paragraph applies only to the LAGPLv3
65  * components listed above.) If you modify this Program, or
66  * any covered work, by linking or combining it with other
67  * code, such other code is not for that reason alone subject
68  * to any of the requirements of the GNU Affero GPL version 3.
69  * (==> This means if you are only using the OT API, then you
70  * don't have to open-source your code--only your changes to
71  * Open-Transactions itself must be open source. Similar to
72  * LGPLv3, except it applies to software-as-a-service, not
73  * just to distributing binaries.)
74  *
75  * Extra WAIVER for OpenSSL, Lucre, and all other libraries
76  * used by Open Transactions: This program is released under
77  * the AGPL with the additional exemption that compiling,
78  * linking, and/or using OpenSSL is allowed. The same is true
79  * for any other open source libraries included in this
80  * project: complete waiver from the AGPL is hereby granted to
81  * compile, link, and/or use them with Open-Transactions,
82  * according to their own terms, as long as the rest of the
83  * Open-Transactions terms remain respected, with regard to
84  * the Open-Transactions code itself.
85  *
86  * Lucre License:
87  * This code is also "dual-license", meaning that Ben Lau-
88  * rie's license must also be included and respected, since
89  * the code for Lucre is also included with Open Transactions.
90  * See Open-Transactions/src/otlib/lucre/LUCRE_LICENSE.txt
91  * The Laurie requirements are light, but if there is any
92  * problem with his license, simply remove the Lucre code.
93  * Although there are no other blind token algorithms in Open
94  * Transactions (yet. credlib is coming), the other functions
95  * will continue to operate.
96  * See Lucre on Github: https://github.com/benlaurie/lucre
97  * -----------------------------------------------------
98  * You should have received a copy of the GNU Affero General
99  * Public License along with this program. If not, see:
100  * http://www.gnu.org/licenses/
101  *
102  * If you would like to use this software outside of the free
103  * software license, please contact FellowTraveler.
104  * (Unfortunately many will run anonymously and untraceably,
105  * so who could really stop them?)
106  *
107  * DISCLAIMER:
108  * This program is distributed in the hope that it will be
109  * useful, but WITHOUT ANY WARRANTY; without even the implied
110  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
111  * PURPOSE. See the GNU Affero General Public License for
112  * more details.
113 
114  -----BEGIN PGP SIGNATURE-----
115  Version: GnuPG v1.4.9 (Darwin)
116 
117  iQIcBAEBAgAGBQJRSsfJAAoJEAMIAO35UbuOQT8P/RJbka8etf7wbxdHQNAY+2cC
118  vDf8J3X8VI+pwMqv6wgTVy17venMZJa4I4ikXD/MRyWV1XbTG0mBXk/7AZk7Rexk
119  KTvL/U1kWiez6+8XXLye+k2JNM6v7eej8xMrqEcO0ZArh/DsLoIn1y8p8qjBI7+m
120  aE7lhstDiD0z8mwRRLKFLN2IH5rAFaZZUvj5ERJaoYUKdn4c+RcQVei2YOl4T0FU
121  LWND3YLoH8naqJXkaOKEN4UfJINCwxhe5Ke9wyfLWLUO7NamRkWD2T7CJ0xocnD1
122  sjAzlVGNgaFDRflfIF4QhBx1Ddl6wwhJfw+d08bjqblSq8aXDkmFA7HeunSFKkdn
123  oIEOEgyj+veuOMRJC5pnBJ9vV+7qRdDKQWaCKotynt4sWJDGQ9kWGWm74SsNaduN
124  TPMyr9kNmGsfR69Q2Zq/FLcLX/j8ESxU+HYUB4vaARw2xEOu2xwDDv6jt0j3Vqsg
125  x7rWv4S/Eh18FDNDkVRChiNoOIilLYLL6c38uMf1pnItBuxP3uhgY6COm59kVaRh
126  nyGTYCDYD2TK+fI9o89F1297uDCwEJ62U0Q7iTDp5QuXCoxkPfv8/kX6lS6T3y9G
127  M9mqIoLbIQ1EDntFv7/t6fUTS2+46uCrdZWbQ5RjYXdrzjij02nDmJAm2BngnZvd
128  kamH0Y/n11lCvo1oQxM+
129  =uSzz
130  -----END PGP SIGNATURE-----
131  **************************************************************/
132 
133 #include "stdafx.hpp"
134 
135 #include "OTIdentifier.hpp"
136 #include "OTContract.hpp"
137 #include "crypto/OTCachedKey.hpp"
138 #include "crypto/OTCrypto.hpp"
139 #include "OTPseudonym.hpp"
140 #include "crypto/OTSymmetricKey.hpp"
141 
142 namespace opentxs
143 {
144 
145 std::ostream& operator<<(std::ostream& os, const OTIdentifier& obj)
146 {
147  OTString str;
148  obj.GetString(str);
149  os << str;
150  return os;
151 }
152 
154  : OTData()
155 {
156 }
157 
159  : OTData(theID)
160 {
161 }
162 
163 OTIdentifier::OTIdentifier(const char* szStr)
164  : OTData()
165 {
166  OT_ASSERT(nullptr != szStr);
167  SetString(szStr);
168 }
169 
170 OTIdentifier::OTIdentifier(const std::string& theStr)
171  : OTData()
172 {
173  OT_ASSERT(!theStr.empty());
174  SetString(theStr.c_str());
175 }
176 
178  : OTData()
179 {
180  SetString(theStr);
181 }
182 
184  : OTData() // Get the contract's ID into this identifier.
185 {
186  (const_cast<OTContract&>(theContract)).GetIdentifier(*this);
187 }
188 
190  : OTData() // Get the Nym's ID into this identifier.
191 {
192  (const_cast<OTPseudonym&>(theNym)).GetIdentifier(*this);
193 }
194 
196  : OTData() // Get the Symmetric Key's ID into *this. (It's a hash of the
197  // encrypted form of the symmetric key.)
198 {
199  (const_cast<OTSymmetricKey&>(theKey)).GetIdentifier(*this);
200 }
201 
203  : OTData() // Cached Key stores a symmetric key inside, so this actually
204  // captures the ID for that symmetrickey.
205 {
206  const bool bSuccess =
207  (const_cast<OTCachedKey&>(theKey)).GetIdentifier(*this);
208 
209  OT_ASSERT(bSuccess); // should never fail. If it does, then we are calling
210  // this function at a time we shouldn't, when we aren't
211  // sure the master key has even been generated yet. (If
212  // this asserts, need to examine the line of code that
213  // tried to do this, and figure out where its logic
214  // went wrong, since it should have made sure this
215  // would not happen, before constructing like this.)
216 }
217 
218 void OTIdentifier::SetString(const char* szString)
219 {
220  OT_ASSERT(nullptr != szString);
221  const OTString theStr(szString);
222  SetString(theStr);
223 }
224 
226 {
227  const OTString ots1(*this), ots2(s2);
228  return ots1.Compare(ots2);
229 }
230 
232 {
233  const OTString ots1(*this), ots2(s2);
234  return !(ots1.Compare(ots2));
235 }
236 
238 {
239  const OTString ots1(*this), ots2(s2);
240  return ots1.operator>(ots2);
241 }
242 
244 {
245  const OTString ots1(*this), ots2(s2);
246  return ots1.operator<(ots2);
247 }
248 
250 {
251  const OTString ots1(*this), ots2(s2);
252  return ots1.operator<=(ots2);
253 }
254 
256 {
257  const OTString ots1(*this), ots2(s2);
258  return ots1.operator>=(ots2);
259 }
260 
262 {
263 }
264 
265 void OTIdentifier::CopyTo(uint8_t* szNewLocation) const
266 {
267  if (GetSize()) {
268  memcpy((void*)GetPointer(), szNewLocation, GetSize()); // todo cast
269  }
270 }
271 
272 // On the advice of SAMY, our default hash algorithm will be an XOR
273 // of two reputable algorithms. This way, if one of them gets broken,
274 // our signatures are still safe.
275 // Smart, eh? So I named it in his honor.
276 // Using SHA-256 and WHIRLPOOL
277 // We now have 256-bit keysize, though half of WHIRLPOOL output is still XORed
278 // onto it.
279 // We also now input/output the string values with Base62 instead of Hex. (More
280 // compact.)
281 //
282 
284 const OTString OTIdentifier::HashAlgorithm1("SHA256");
285 const OTString OTIdentifier::HashAlgorithm2("WHIRLPOOL");
286 
287 // This method implements the SAMY hash
289 {
290  OTIdentifier idSecondHash;
291 
292  if (idSecondHash.CalculateDigest(strInput, HashAlgorithm2) &&
293  CalculateDigest(strInput, HashAlgorithm1)) {
294  // At this point, we have successfully generated the WHRLPOOL hash in
295  // idSecondHash, and we've successfully generated the SHA-256 hash in
296  // this object.
297  // Next we XOR them together for the final product.
298  return XOR(idSecondHash);
299  }
300 
301  return false;
302 }
303 
304 // This method implements the SAMY hash
305 bool OTIdentifier::CalculateDigest(const OTData& dataInput)
306 {
307  OTIdentifier idSecondHash;
308 
309  if (idSecondHash.CalculateDigest(dataInput, HashAlgorithm2) &&
310  CalculateDigest(dataInput, HashAlgorithm1)) {
311  // At this point, we have successfully generated the WHRLPOOL hash in
312  // idSecondHash, and we've successfully generated the SHA-256 hash in
313  // this object.
314  // Next we XOR them together for the final product.
315  return XOR(idSecondHash);
316  }
317 
318  return false;
319 }
320 
321 // Some of the digest calculations are done by crypto++, instead of OpenSSL.
322 // (UPDATE that is no longer true.)
323 // Also, at least one of the algorithms (SAMY) is an internal name, and again
324 // not
325 // handled by OpenSSL. So I call this function first to see if the hash type
326 // requres
327 // internal handling. If not, then I return false and the caller knows to use
328 // OpenSSL
329 // instead.
331  const OTString& strHashAlgorithm)
332 {
333  // See if they wanted to use the SAMY hash
334  if (strHashAlgorithm.Compare(DefaultHashAlgorithm)) {
335  return CalculateDigest(strInput);
336  }
337 
338  return false;
339 }
340 
341 // Some of the digest calculations are done by crypto++, instead of OpenSSL.
342 // (UPDATE: above is no longer true...)
343 // Also, at least one of the algorithms (SAMY) is an internal name, and again
344 // not
345 // handled by OpenSSL. So I call this function first to see if the hash type
346 // requres
347 // internal handling. If not, then I return false and the caller knows to use
348 // OpenSSL
349 // instead.
350 
352  const OTString& strHashAlgorithm)
353 {
354  // See if they wanted to use the SAMY hash
355  if (strHashAlgorithm.Compare(DefaultHashAlgorithm)) {
356  return CalculateDigest(dataInput);
357  }
358 
359  return false;
360 }
361 
362 // This function lets you choose the hash algorithm by string.
363 // (For example, if you read "SHA-256" out of a signed file and you
364 // needed to get the hash function based on that string, you could use this.)
365 //
367  const OTString& strHashAlgorithm)
368 {
369  return OTCrypto::It()->CalculateDigest(strInput, strHashAlgorithm, *this);
370 }
371 
372 bool OTIdentifier::CalculateDigest(const OTData& dataInput,
373  const OTString& strHashAlgorithm)
374 {
375  return OTCrypto::It()->CalculateDigest(dataInput, strHashAlgorithm, *this);
376 }
377 
378 // So we can implement the SAMY hash, which is currently an XOR of SHA-256 with
379 // WHRLPOOL
380 //
381 // Originally, it was SHA512 and WHRLPOOL, which both have a 512-bit
382 // output-size.
383 // I was then going to cut the result in half and XOR together again. But then I
384 // though, for now, instead of doing all that extra work, I'll just change the
385 // two "HashAlgorithms" from SHA512 and WHRLPOOL to SHA256 and WHIRLPOOL.
386 //
387 // This was very much easier, as I only had to change the little "512" to say
388 // "256" instead, and basically the job was done. Of course, this means that OT
389 // is generating a 256-bit hash in THIS object, and a 512-bit WHIRLPOOL hash in
390 // the other object. i.e. There is still one 512-bit hash that you are forced to
391 // calculate, even if you throw away half of it after the calculation is done.
392 //
393 // Since the main object has a 256-bit hash, the XOR() function below was
394 // already
395 // coded to XOR the minimum length based on the smallest of the two objects.
396 // Therefore, it will XOR 256 bits of the WHRLPOOL output into the 256 bits of
397 // the main output (SHA256) and stop there: we now have a 256 bit ID.
398 //
399 // The purpose here is to reduce the ID size so that it will work on Windows
400 // with
401 // the filenames. The current 512bit output is 64 bytes, or 128 characters when
402 // exported to a hex string (in all the OT contracts for example, over and over
403 // again.)
404 //
405 // The new size will be 256bit, which is 32 bytes of binary. In hex string that
406 // would be 64 characters. But we're also converting from Hex to Base62, which
407 // means we'll get it down to around 43 characters.
408 //
409 // This means our IDs are going to go from this:
410 //
411 //
412 // To this:
413 //
414 //
415 // You might ask: is 256 bits big enough of a hash size to be safe from
416 // collisions?
417 // Practically speaking, I believe so. The IDs are used for accounts, servers,
418 // asset types,
419 // and users. How many different asset types do you expect there will be, where
420 // changing the
421 // contract to anything still intelligible would result in a still-valid
422 // signature? To find
423 // a collision in a contract, where the signature would still work, would you
424 // expect the necessary
425 // changed plaintext to be something that would still make sense in the
426 // contract? Would such
427 // a random piece of data turn out to form proper XML?
428 //
429 // 256bits is enough to store the number of atoms in the Universe. If we ever
430 // need a bigger
431 // hashsize, just go change the HashAlgorithm1 back to "SHA512" instead of
432 // "SHA256", and you'll
433 // instantly have a doubled hash output size :-)
434 //
435 bool OTIdentifier::XOR(const OTIdentifier& theInput) const
436 {
437  // Go with the smallest of the two
438  const int64_t lSize =
439  (GetSize() > theInput.GetSize() ? theInput.GetSize() : GetSize());
440 
441  for (int32_t i = 0; i < lSize; i++) {
442  // When converting to BigInteger internally, this will be a bit more
443  // efficient.
444  ((char*)GetPointer())[i] ^=
445  ((char*)theInput.GetPointer())[i]; // todo cast
446  }
447 
448  return true;
449 }
450 
451 // SET (binary id) FROM BASE62-ENCODED STRING
452 //
454 {
456  *this); // theStr input, *this output.
457 }
458 
459 // GET (binary id) AS BASE62-ENCODED STRING
460 //
461 // This Identifier is stored in binary form.
462 // But what if you want a pretty base62 string version of it?
463 // Just call this function.
464 //
466 {
468  *this, theStr); // *this input, theStr output.
469 }
470 
471 } // namespace opentxs
static EXPORT OTCrypto * It()
Definition: OTCrypto.cpp:630
std::ostream & operator<<(std::ostream &os, const OTIdentifier &obj)
EXPORT bool CalculateDigest(const OTData &dataInput)
EXPORT bool operator!=(const OTIdentifier &s2) const
static EXPORT const OTString HashAlgorithm2
EXPORT bool operator>(const OTIdentifier &s2) const
virtual EXPORT ~OTIdentifier()
EXPORT void SetString(const char *szString)
EXPORT bool operator>=(const OTIdentifier &s2) const
EXPORT bool CalculateDigestInternal(const OTString &strInput, const OTString &strHashAlgorithm)
EXPORT bool XOR(const OTIdentifier &theInput) const
EXPORT bool Compare(const char *compare) const
Definition: OTString.cpp:1102
#define OT_ASSERT(x)
Definition: Assert.hpp:150
static EXPORT const OTString DefaultHashAlgorithm
EXPORT bool operator==(const OTIdentifier &s2) const
virtual bool CalculateDigest(const OTString &strInput, const OTString &strHashAlgorithm, OTIdentifier &theOutput) const =0
const void * GetPointer() const
Definition: OTData.hpp:162
EXPORT bool operator<=(const OTIdentifier &s2) const
EXPORT void GetString(OTString &theStr) const
EXPORT void CopyTo(uint8_t *szNewLocation) const
virtual void SetBase62StringFromID(const OTIdentifier &theInput, OTString &strOutput) const =0
virtual void SetIDFromBase62String(const OTString &strInput, OTIdentifier &theOutput) const =0
uint32_t GetSize() const
Definition: OTData.hpp:174
EXPORT bool operator<(const OTIdentifier &s2) const
static EXPORT const OTString HashAlgorithm1