bool BankTool::isCoinDoubleSpent(const Coin &coin1, const Coin &coin2) const { // throw an exception if these coins do not share the same S value if(coin1.getSPrime() != coin2.getSPrime()) { throw CashException(CashException::CE_UNKNOWN_ERROR, "[BankTool::checkIfCoinDoubleSpent] Coins do not share same serial " "coin point and are not valid candidates for checking double " "spending."); } // if contract hashes are same, then both coins were spent in the same // transaction so the coin was not double spent return (coin1.getR() != coin2.getR()); }
ZZ BankTool::identifyDoubleSpender(const Coin& coin1, const ZZ &tPrime2, const ZZ& rValue2) const { // Should probably check that the R values are different ZZ mod = coin1.getCashGroup()->getModulus(); ZZ order = coin1.getCashGroup()->getOrder(); ZZ t1 = coin1.getTPrime(); ZZ t2 = tPrime2; ZZ r1 = coin1.getR(); ZZ r2 = rValue2; if (r2 > r1) { NTL::swap(r2, r1); NTL::swap(t2, t1); } ZZ exp = InvMod(r1 - r2, order); ZZ num = PowerMod(t2, r1, mod); ZZ denom = InvMod(PowerMod(t1, r2, mod), mod); ZZ base = MulMod(num, denom, mod); ZZ publicKeyUser = PowerMod(base, exp, mod); return publicKeyUser; }
ZZ BankTool::identifyDoubleSpender(const Coin& coin1, const Coin& coin2) const { return identifyDoubleSpender(coin1, coin2.getTPrime(), coin2.getR()); }