/*
* hashtree.h
- * serp++
+ * hashing, Merkle hash trees and data integrity
*
* Created by Victor Grishchenko on 3/6/09.
* Copyright 2009 Delft University of Technology. All rights reserved.
*
*/
-#ifndef P2TP_SHA1_HASH_TREE_H
-#define P2TP_SHA1_HASH_TREE_H
+#ifndef SWIFT_SHA1_HASH_TREE_H
+#define SWIFT_SHA1_HASH_TREE_H
#include "bin64.h"
#include "bins.h"
#include <string.h>
#include <string>
-namespace p2tp {
+namespace swift {
+/** SHA-1 hash, 20 bytes of data */
struct Sha1Hash {
uint8_t bits[20];
Sha1Hash() { memset(bits,0,20); }
+ /** Make a hash of two hashes (for building Merkle hash trees). */
Sha1Hash(const Sha1Hash& left, const Sha1Hash& right);
+ /** Hash an old plain string. */
Sha1Hash(const char* str, size_t length=-1);
Sha1Hash(const uint8_t* data, size_t length);
+ /** Either parse hash from hex representation of read in raw format. */
Sha1Hash(bool hex, const char* hash);
std::string hex() const;
};
+/** This class controls data integrity of some file; hash tree is put to
+ an auxilliary file next to it. The hash tree file is mmap'd for
+ performance reasons. Actually, I'd like the data file itself to be
+ mmap'd, but 32-bit platforms do not allow that for bigger files.
+
+ There are two variants of the general workflow: either a HashTree
+ is initialized with a root hash and the rest of hashes and data is
+ spoon-fed later, OR a HashTree is initialized with a data file, so
+ the hash tree is derived, including the root hash.
+ */
class HashTree {
/** Merkle hash tree: root */
/** Part of the tree currently checked. */
size_t complete_;
size_t completek_;
- bins ack_out_;
+ binmap_t ack_out_;
protected:
/** Offer data; the behavior is the same as with a hash:
accept or remember or drop. Returns true => ACK is sent. */
bool OfferData (bin64_t bin, const char* data, size_t length);
- /** Not implemented yet. */
+ /** For live streaming. Not implemented yet. */
int AppendData (char* data, int length) ;
int file_descriptor () const { return fd_; }
+ /** Returns the number of peaks (read on peak hashes). */
int peak_count () const { return peak_count_; }
+ /** Returns the i-th peak's bin number. */
bin64_t peak (int i) const { return peaks_[i]; }
+ /** Returns peak hash #i. */
const Sha1Hash& peak_hash (int i) const { return peak_hashes_[i]; }
+ /** Return the peak bin the given bin belongs to. */
bin64_t peak_for (bin64_t pos) const;
+ /** Return a (Merkle) hash for the given bin. */
const Sha1Hash& hash (bin64_t pos) const {return hashes_[pos];}
+ /** Give the root hash, which is effectively an identifier of this file. */
const Sha1Hash& root_hash () const { return root_hash_; }
+ /** Get file size, in bytes. */
uint64_t size () const { return size_; }
+ /** Get file size in packets (in kilobytes, rounded up). */
uint64_t packet_size () const { return sizek_; }
+ /** Number of bytes retrieved and checked. */
uint64_t complete () const { return complete_; }
+ /** Number of packets retrieved and checked. */
uint64_t packets_complete () const { return completek_; }
+ /** The number of bytes completed sequentially, i.e. from the beginning of
+ the file, uninterrupted. */
uint64_t seq_complete () ;
+ /** Whether the file is complete. */
bool is_complete ()
{ return size_ && complete_==size_; }
- bins& ack_out () { return ack_out_; }
+ /** The binmap of complete packets. */
+ binmap_t& ack_out () { return ack_out_; }
~HashTree ();