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