forked from Zerocoin/libzerocoin
/
Accumulator.cpp
106 lines (86 loc) · 2.84 KB
/
Accumulator.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/**
* @file Accumulator.cpp
*
* @brief Accumulator and AccumulatorWitness classes for the Zerocoin library.
*
* @author Ian Miers, Christina Garman and Matthew Green
* @date June 2013
*
* @copyright Copyright 2013 Ian Miers, Christina Garman and Matthew Green
* @license This project is released under the MIT license.
**/
#include <sstream>
#include "Zerocoin.h"
namespace libzerocoin {
//Accumulator class
Accumulator::Accumulator(const AccumulatorAndProofParams* p, const CoinDenomination d): params(p), denomination(d) {
if (!(params->initialized)) {
throw ZerocoinException("Invalid parameters for accumulator");
}
this->value = this->params->accumulatorBase;
}
Accumulator::Accumulator(const Params* p, const CoinDenomination d) {
this->params = &(p->accumulatorParams);
this->denomination = d;
if (!(params->initialized)) {
throw ZerocoinException("Invalid parameters for accumulator");
}
this->value = this->params->accumulatorBase;
}
void Accumulator::accumulate(const PublicCoin& coin) {
// Make sure we're initialized
if(!(this->value)) {
throw ZerocoinException("Accumulator is not initialized");
}
if(this->denomination != coin.getDenomination()) {
//std::stringstream msg;
std::string msg;
msg = "Wrong denomination for coin. Expected coins of denomination: ";
msg += this->denomination;
msg += ". Instead, got a coin of denomination: ";
msg += coin.getDenomination();
throw std::invalid_argument(msg);
}
if(coin.validate()) {
// Compute new accumulator = "old accumulator"^{element} mod N
this->value = this->value.pow_mod(coin.getValue(), this->params->accumulatorModulus);
} else {
throw std::invalid_argument("Coin is not valid");
}
}
const CoinDenomination Accumulator::getDenomination() const {
return static_cast<CoinDenomination> (this->denomination);
}
const Bignum& Accumulator::getValue() const {
return this->value;
}
Accumulator& Accumulator::operator += (const PublicCoin& c) {
this->accumulate(c);
return *this;
}
bool Accumulator::operator == (const Accumulator rhs) const {
return this->value == rhs.value;
}
//AccumulatorWitness class
AccumulatorWitness::AccumulatorWitness(const Params* p,
const Accumulator& checkpoint, const PublicCoin coin): params(p), witness(checkpoint), element(coin) {
}
void AccumulatorWitness::AddElement(const PublicCoin& c) {
if(element != c) {
witness += c;
}
}
const Bignum& AccumulatorWitness::getValue() const {
return this->witness.getValue();
}
bool AccumulatorWitness::VerifyWitness(const Accumulator& a, const PublicCoin &publicCoin) const {
Accumulator temp(witness);
temp += element;
return (temp == a && this->element == publicCoin);
}
AccumulatorWitness& AccumulatorWitness::operator +=(
const PublicCoin& rhs) {
this->AddElement(rhs);
return *this;
}
} /* namespace libzerocoin */