PIVX Core  5.6.99
P2P Digital Currency
CoinRandomnessSchnorrSignature.cpp
Go to the documentation of this file.
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 
6 
7 namespace libzerocoin {
8 
10  const ZerocoinParams* zcparams, const CBigNum randomness, const uint256 msghash)
11 {
12  const CBigNum p = zcparams->coinCommitmentGroup.modulus;
13  const CBigNum q = zcparams->coinCommitmentGroup.groupOrder;
14  const CBigNum h = zcparams->coinCommitmentGroup.h;
15  const CBigNum pk = h.pow_mod(randomness, p);
16 
17  alpha = 0;
18  beta = 0;
19 
20  CBigNum k, r;
21 
22  while (!alpha || !beta) {
23  // select random nonce k in Zq and let r = h^k mod p
24  k = CBigNum::randBignum(q);
25  r = h.pow_mod(k, p);
26 
27  // challenge hash
28  CHashWriter hasher(0,0);
29  hasher << *zcparams << pk << r << msghash;
30  alpha = CBigNum(hasher.GetHash()) % q;
31  beta = (k - alpha.mul_mod(randomness, q)) % q;
32  }
33 
34 }
35 
37  const ZerocoinParams* zcparams, const CBigNum& S, const CBigNum& C, const uint256 msghash) const
38 {
39  const CBigNum p = zcparams->coinCommitmentGroup.modulus;
40  const CBigNum q = zcparams->coinCommitmentGroup.groupOrder;
41  const CBigNum h = zcparams->coinCommitmentGroup.h;
42  const CBigNum g = zcparams->coinCommitmentGroup.g;
43 
44  // Params validation.
45  if (!IsValidSerial(zcparams, S)) return error("%s: Invalid serial range", __func__);
46  if (alpha < BN_ZERO || alpha >= q) return error("%s: alpha out of range", __func__);
47  if (beta < BN_ZERO || beta >= q) return error("%s: beta out of range", __func__);
48 
49  // Schnorr public key computation.
50  const CBigNum pk = C.mul_mod(g.pow_mod(-S,p),p);
51 
52  // Signature verification.
53  const CBigNum rv = (pk.pow_mod(alpha,p)).mul_mod(h.pow_mod(beta,p),p);
54  CHashWriter hasher(0,0);
55  hasher << *zcparams << pk << rv << msghash;
56 
57  if (CBigNum(hasher.GetHash()) % q != alpha)
58  return error("%s: Schnorr signature does not verify", __func__);
59 
60  return true;
61 
62 }
63 
64 } /* namespace libzerocoin */
C++ wrapper for BIGNUM.
Definition: bignum.h:35
CBigNum pow_mod(const CBigNum &e, const CBigNum &m) const
modular exponentiation: this^e mod n
Definition: bignum.cpp:220
static CBigNum randBignum(const CBigNum &range)
Generates a cryptographically secure random number between zero and range exclusive i....
Definition: bignum.cpp:58
CBigNum mul_mod(const CBigNum &b, const CBigNum &m) const
modular multiplication: (this * b) mod m
Definition: bignum.cpp:207
A writer stream (for serialization) that computes a 256-bit hash.
Definition: hash.h:216
uint256 GetHash()
Definition: hash.h:236
bool Verify(const ZerocoinParams *zcparams, const CBigNum &S, const CBigNum &C, const uint256 msghash) const
Verifies the Schnorr signature on message msghash with public key pk = Cg^-S mod p.
CBigNum groupOrder
The order of the group.
Definition: Params.h:57
CBigNum h
A second generator for the group.
Definition: Params.h:47
CBigNum modulus
The modulus for the group.
Definition: Params.h:52
CBigNum g
A generator for the group.
Definition: Params.h:40
IntegerGroupParams coinCommitmentGroup
The Quadratic Residue group from which we form a coin as a commitment to a serial number.
Definition: Params.h:169
256-bit opaque blob.
Definition: uint256.h:138
#define S(x0, x1, x2, x3, cb, r)
Definition: jh.c:494
bool IsValidSerial(const ZerocoinParams *params, const CBigNum &bnSerial)
Definition: Coin.cpp:87
bool error(const char *fmt, const Args &... args)
Definition: system.h:77