Line data Source code
1 : // Copyright (c) 2019 The PIVX Core developers 2 : // Distributed under the MIT/X11 software license, see the accompanying 3 : // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 : 5 : #include "CoinRandomnessSchnorrSignature.h" 6 : 7 : namespace libzerocoin { 8 : 9 0 : CoinRandomnessSchnorrSignature::CoinRandomnessSchnorrSignature( 10 0 : const ZerocoinParams* zcparams, const CBigNum randomness, const uint256 msghash) 11 : { 12 0 : const CBigNum p = zcparams->coinCommitmentGroup.modulus; 13 0 : const CBigNum q = zcparams->coinCommitmentGroup.groupOrder; 14 0 : const CBigNum h = zcparams->coinCommitmentGroup.h; 15 0 : const CBigNum pk = h.pow_mod(randomness, p); 16 : 17 0 : alpha = 0; 18 0 : beta = 0; 19 : 20 0 : CBigNum k, r; 21 : 22 0 : while (!alpha || !beta) { 23 : // select random nonce k in Zq and let r = h^k mod p 24 0 : k = CBigNum::randBignum(q); 25 0 : r = h.pow_mod(k, p); 26 : 27 : // challenge hash 28 0 : CHashWriter hasher(0,0); 29 0 : hasher << *zcparams << pk << r << msghash; 30 0 : alpha = CBigNum(hasher.GetHash()) % q; 31 0 : beta = (k - alpha.mul_mod(randomness, q)) % q; 32 : } 33 : 34 0 : } 35 : 36 0 : bool CoinRandomnessSchnorrSignature::Verify( 37 : const ZerocoinParams* zcparams, const CBigNum& S, const CBigNum& C, const uint256 msghash) const 38 : { 39 0 : const CBigNum p = zcparams->coinCommitmentGroup.modulus; 40 0 : const CBigNum q = zcparams->coinCommitmentGroup.groupOrder; 41 0 : const CBigNum h = zcparams->coinCommitmentGroup.h; 42 0 : const CBigNum g = zcparams->coinCommitmentGroup.g; 43 : 44 : // Params validation. 45 0 : if (!IsValidSerial(zcparams, S)) return error("%s: Invalid serial range", __func__); 46 0 : if (alpha < BN_ZERO || alpha >= q) return error("%s: alpha out of range", __func__); 47 0 : if (beta < BN_ZERO || beta >= q) return error("%s: beta out of range", __func__); 48 : 49 : // Schnorr public key computation. 50 0 : const CBigNum pk = C.mul_mod(g.pow_mod(-S,p),p); 51 : 52 : // Signature verification. 53 0 : const CBigNum rv = (pk.pow_mod(alpha,p)).mul_mod(h.pow_mod(beta,p),p); 54 0 : CHashWriter hasher(0,0); 55 0 : hasher << *zcparams << pk << rv << msghash; 56 : 57 0 : if (CBigNum(hasher.GetHash()) % q != alpha) 58 0 : return error("%s: Schnorr signature does not verify", __func__); 59 : 60 : return true; 61 : 62 : } 63 : 64 : } /* namespace libzerocoin */