bool CKey::Verify(uint256 hash, const std::vector<unsigned char>& vchSig) { // decode the vchSig Integer sigE, sigS; if (vchSig.size() != (SCHNORR_SIG_SIZE * 2)) return false; // extract bytes std::vector<unsigned char> sigEVec(&vchSig[0], &vchSig[SCHNORR_SIG_SIZE]); std::vector<unsigned char> sigSVec(&vchSig[SCHNORR_SIG_SIZE], &vchSig[1 + SCHNORR_SIG_SIZE * 2]); // vectors -> Integers sigE.Decode(&sigEVec[0], SCHNORR_SIG_SIZE); sigS.Decode(&sigSVec[0], SCHNORR_SIG_SIZE); // verify the hash ECPPoint R; R = ec.CascadeScalarMultiply(G, sigS, Q, sigE); // encode hash as byte[] std::vector<unsigned char> vchHash = hash.toVch(); Integer sigEd = HashPointMessage(R, &vchHash[0], sizeof(hash)) % q; return (sigE == sigEd); }
bool CKey::Sign(uint256 hash, std::vector<unsigned char>& vchSig) { // sign the hash Integer k; ECPPoint R; Integer sigE, sigS; k = Integer(rng, 256) % q; R = ec.ScalarMultiply(G, k); // encode hash as byte[] std::vector<unsigned char> vchHash = hash.toVch(); sigE = HashPointMessage(R, &vchHash[0], sizeof(hash)) % q; sigS = (k - secretKey*sigE) % q; // encode the vch format vchSig.resize(SCHNORR_SIG_SIZE * 2); if (sigE.MinEncodedSize() > SCHNORR_SIG_SIZE || sigS.MinEncodedSize() > SCHNORR_SIG_SIZE) return false; sigE.Encode(&vchSig[0], SCHNORR_SIG_SIZE); sigS.Encode(&vchSig[SCHNORR_SIG_SIZE], SCHNORR_SIG_SIZE); return true; }