Esempio n. 1
0
template <class Element, class Iterator> Element GeneralCascadeMultiplication(const AbstractGroup<Element> &group, Iterator begin, Iterator end)
{
	if (end-begin == 1)
		return group.ScalarMultiply(begin->base, begin->exponent);
	else if (end-begin == 2)
		return group.CascadeScalarMultiply(begin->base, begin->exponent, (begin+1)->base, (begin+1)->exponent);
	else
	{
		Integer q, t;
		Iterator last = end;
		--last;

		std::make_heap(begin, end);
		std::pop_heap(begin, end);

		while (!!begin->exponent)
		{
			// last->exponent is largest exponent, begin->exponent is next largest
			t = last->exponent;
			Integer::Divide(last->exponent, q, t, begin->exponent);

			if (q == Integer::One())
				group.Accumulate(begin->base, last->base);	// avoid overhead of ScalarMultiply()
			else
				group.Accumulate(begin->base, group.ScalarMultiply(last->base, q));

			std::push_heap(begin, end);
			std::pop_heap(begin, end);
		}

		return group.ScalarMultiply(last->base, last->exponent);
	}
}
Esempio n. 2
0
template <class Element, class Iterator> Element GeneralCascadeMultiplication(const AbstractGroup<Element> &group, Iterator begin, Iterator end)
{
	if (end-begin == 1)
		return group.IntMultiply((*begin).second, (*begin).first);
	else if (end-begin == 2)
		return group.CascadeIntMultiply((*begin).second, (*begin).first, (*(begin+1)).second, (*(begin+1)).first);
	else
	{
		Integer q, r;
		Iterator last = end;
		--last;

		std::make_heap(begin, end);
		std::pop_heap(begin, end);

		while (!!(*begin).first)
		{
			// (*last).first is largest exponent, (*begin).first is next largest
			Integer::Divide(r, q, (*last).first, (*begin).first);

			if (q == Integer::One())
				group.Accumulate((*begin).second, (*last).second);	// avoid overhead of GeneralizedMultiplication()
			else
				group.Accumulate((*begin).second, group.IntMultiply((*last).second, q));

			(*last).first = r;

			std::push_heap(begin, end);
			std::pop_heap(begin, end);
		}

		return group.IntMultiply((*last).second, (*last).first);
	}
}
Esempio n. 3
0
void SimultaneousMultiplication(Iterator result, const AbstractGroup<Element> &group, const Element &base, ConstIterator expBegin, ConstIterator expEnd)
{
	unsigned int expCount = std::distance(expBegin, expEnd);

	std::vector<WindowSlider<Element> > exponents(expCount);
	unsigned int i;

	bool notDone = false;
	for (i=0; i<expCount; i++)
		notDone = exponents[i].FindFirstWindow(group, *expBegin++) || notDone;

	unsigned int expBitPosition = 0;
	Element g = base;
	while (notDone)
	{
		notDone = false;
		for (i=0; i<expCount; i++)
		{
			if (expBitPosition < exponents[i].expLen && expBitPosition == exponents[i].windowBegin)
			{
				Element &bucket = exponents[i].buckets[exponents[i].nextBucket];
				group.Accumulate(bucket, g);
				exponents[i].FindNextWindow();
			}
			notDone = notDone || exponents[i].windowBegin < exponents[i].expLen;
		}

		if (notDone)
		{
			g = group.Double(g);
			expBitPosition++;
		}
	}

	for (i=0; i<expCount; i++)
	{
		Element &r = *result++;
		std::vector<Element> &buckets = exponents[i].buckets;
		r = buckets[buckets.size()-1];
		if (buckets.size() > 1)
		{
			for (int j = buckets.size()-2; j >= 1; j--)
			{
				group.Accumulate(buckets[j], buckets[j+1]);
				group.Accumulate(r, buckets[j]);
			}
			group.Accumulate(buckets[0], buckets[1]);
			r = group.Add(group.Double(r), buckets[0]);
		}
	}
}