1#ifndef CRYPTOPP_IDA_H
2#define CRYPTOPP_IDA_H
3
4#include "mqueue.h"
5#include "filters.h"
6#include "channels.h"
7#include <map>
8#include <vector>
9
10NAMESPACE_BEGIN(CryptoPP)
11
12/// base class for secret sharing and information dispersal
13class RawIDA : public AutoSignaling<Unflushable<Multichannel<Filter> > >
14{
15public:
16	RawIDA(BufferedTransformation *attachment=NULL)
17		{Detach(attachment);}
18
19	unsigned int GetThreshold() const {return m_threshold;}
20	void AddOutputChannel(word32 channelId);
21	void ChannelData(word32 channelId, const byte *inString, size_t length, bool messageEnd);
22	lword InputBuffered(word32 channelId) const;
23
24	void IsolatedInitialize(const NameValuePairs &parameters=g_nullNameValuePairs);
25	size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking)
26	{
27		if (!blocking)
28			throw BlockingInputOnly("RawIDA");
29		ChannelData(StringToWord<word32>(channel), begin, length, messageEnd != 0);
30		return 0;
31	}
32
33protected:
34	virtual void FlushOutputQueues();
35	virtual void OutputMessageEnds();
36
37	unsigned int InsertInputChannel(word32 channelId);
38	unsigned int LookupInputChannel(word32 channelId) const;
39	void ComputeV(unsigned int);
40	void PrepareInterpolation();
41	void ProcessInputQueues();
42
43	typedef std::map<word32, unsigned int> InputChannelMap;
44	InputChannelMap m_inputChannelMap;
45	InputChannelMap::iterator m_lastMapPosition;
46	std::vector<MessageQueue> m_inputQueues;
47	std::vector<word32> m_inputChannelIds, m_outputChannelIds, m_outputToInput;
48	std::vector<std::string> m_outputChannelIdStrings;
49	std::vector<ByteQueue> m_outputQueues;
50	int m_threshold;
51	unsigned int m_channelsReady, m_channelsFinished;
52	std::vector<SecBlock<word32> > m_v;
53	SecBlock<word32> m_u, m_w, m_y;
54};
55
56/// a variant of Shamir's Secret Sharing Algorithm
57class SecretSharing : public CustomFlushPropagation<Filter>
58{
59public:
60	SecretSharing(RandomNumberGenerator &rng, int threshold, int nShares, BufferedTransformation *attachment=NULL, bool addPadding=true)
61		: m_rng(rng), m_ida(new OutputProxy(*this, true))
62	{
63		Detach(attachment);
64		IsolatedInitialize(MakeParameters("RecoveryThreshold", threshold)("NumberOfShares", nShares)("AddPadding", addPadding));
65	}
66
67	void IsolatedInitialize(const NameValuePairs &parameters=g_nullNameValuePairs);
68	size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking);
69	bool Flush(bool hardFlush, int propagation=-1, bool blocking=true) {return m_ida.Flush(hardFlush, propagation, blocking);}
70
71protected:
72	RandomNumberGenerator &m_rng;
73	RawIDA m_ida;
74	bool m_pad;
75};
76
77/// a variant of Shamir's Secret Sharing Algorithm
78class SecretRecovery : public RawIDA
79{
80public:
81	SecretRecovery(int threshold, BufferedTransformation *attachment=NULL, bool removePadding=true)
82		: RawIDA(attachment)
83		{IsolatedInitialize(MakeParameters("RecoveryThreshold", threshold)("RemovePadding", removePadding));}
84
85	void IsolatedInitialize(const NameValuePairs &parameters=g_nullNameValuePairs);
86
87protected:
88	void FlushOutputQueues();
89	void OutputMessageEnds();
90
91	bool m_pad;
92};
93
94/// a variant of Rabin's Information Dispersal Algorithm
95class InformationDispersal : public CustomFlushPropagation<Filter>
96{
97public:
98	InformationDispersal(int threshold, int nShares, BufferedTransformation *attachment=NULL, bool addPadding=true)
99		: m_ida(new OutputProxy(*this, true))
100	{
101		Detach(attachment);
102		IsolatedInitialize(MakeParameters("RecoveryThreshold", threshold)("NumberOfShares", nShares)("AddPadding", addPadding));
103	}
104
105	void IsolatedInitialize(const NameValuePairs &parameters=g_nullNameValuePairs);
106	size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking);
107	bool Flush(bool hardFlush, int propagation=-1, bool blocking=true) {return m_ida.Flush(hardFlush, propagation, blocking);}
108
109protected:
110	RawIDA m_ida;
111	bool m_pad;
112	unsigned int m_nextChannel;
113};
114
115/// a variant of Rabin's Information Dispersal Algorithm
116class InformationRecovery : public RawIDA
117{
118public:
119	InformationRecovery(int threshold, BufferedTransformation *attachment=NULL, bool removePadding=true)
120		: RawIDA(attachment)
121		{IsolatedInitialize(MakeParameters("RecoveryThreshold", threshold)("RemovePadding", removePadding));}
122
123	void IsolatedInitialize(const NameValuePairs &parameters=g_nullNameValuePairs);
124
125protected:
126	void FlushOutputQueues();
127	void OutputMessageEnds();
128
129	bool m_pad;
130	ByteQueue m_queue;
131};
132
133class PaddingRemover : public Unflushable<Filter>
134{
135public:
136	PaddingRemover(BufferedTransformation *attachment=NULL)
137		: m_possiblePadding(false) {Detach(attachment);}
138
139	void IsolatedInitialize(const NameValuePairs &parameters) {m_possiblePadding = false;}
140	size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking);
141
142	// GetPossiblePadding() == false at the end of a message indicates incorrect padding
143	bool GetPossiblePadding() const {return m_possiblePadding;}
144
145private:
146	bool m_possiblePadding;
147	lword m_zeroCount;
148};
149
150NAMESPACE_END
151
152#endif
153