bool Base58::raw_decode (char const* first, char const* last, void* dest, std::size_t size, bool checked, Alphabet const& alphabet) { CAutoBN_CTX pctx; CBigNum bn58 = 58; CBigNum bn = 0; CBigNum bnChar; // Convert big endian string to bignum for (char const* p = first; p != last; ++p) { int i (alphabet.from_char (*p)); if (i == -1) return false; bnChar.setuint ((unsigned int) i); int const success (BN_mul (&bn, &bn, &bn58, pctx)); assert (success); (void) success; bn += bnChar; } // Get bignum as little endian data Blob vchTmp = bn.getvch (); // Trim off sign byte if present if (vchTmp.size () >= 2 && vchTmp.end ()[-1] == 0 && vchTmp.end ()[-2] >= 0x80) vchTmp.erase (vchTmp.end () - 1); char* const out (static_cast <char*> (dest)); // Count leading zeros int nLeadingZeros = 0; for (char const* p = first; p!=last && *p==alphabet[0]; p++) nLeadingZeros++; // Verify that the size is correct if (vchTmp.size() + nLeadingZeros != size) return false; // Fill the leading zeros memset (out, 0, nLeadingZeros); // Copy little endian data to big endian std::reverse_copy (vchTmp.begin (), vchTmp.end (), out + nLeadingZeros); if (checked) { char hash4 [4]; fourbyte_hash256 (hash4, out, size - 4); if (memcmp (hash4, out + size - 4, 4) != 0) return false; } return true; }
bool Base58::decode (const char* psz, Blob& vchRet, Alphabet const& alphabet) { CAutoBN_CTX pctx; vchRet.clear (); CBigNum bn58 = 58; CBigNum bn = 0; CBigNum bnChar; while (isspace (*psz)) psz++; // Convert big endian string to bignum for (const char* p = psz; *p; p++) { // VFALCO TODO Make this use the inverse table! // Or better yet ditch this and call raw_decode // const char* p1 = strchr (alphabet.chars(), *p); if (p1 == nullptr) { while (isspace (*p)) p++; if (*p != '\0') return false; break; } bnChar.setuint (p1 - alphabet.chars()); if (!BN_mul (&bn, &bn, &bn58, pctx)) throw bignum_error ("DecodeBase58 : BN_mul failed"); bn += bnChar; } // Get bignum as little endian data Blob vchTmp = bn.getvch (); // Trim off sign byte if present if (vchTmp.size () >= 2 && vchTmp.end ()[-1] == 0 && vchTmp.end ()[-2] >= 0x80) vchTmp.erase (vchTmp.end () - 1); // Restore leading zeros int nLeadingZeros = 0; for (const char* p = psz; *p == alphabet.chars()[0]; p++) nLeadingZeros++; vchRet.assign (nLeadingZeros + vchTmp.size (), 0); // Convert little endian data to big endian std::reverse_copy (vchTmp.begin (), vchTmp.end (), vchRet.end () - vchTmp.size ()); return true; }
inline bool DecodeBase58(const char* psz, vector<unsigned char>& vchRet) { CAutoBN_CTX pctx; vchRet.clear(); CBigNum bn58 = 58; CBigNum bn = 0; CBigNum bnChar; while (isspace(*psz)) psz++; // Convert big endian string to bignum for (const char* p = psz; *p; p++) { const char* p1 = strchr(pszBase58, *p); if (p1 == NULL) { while (isspace(*p)) p++; if (*p != '\0') return false; break; } bnChar.setulong(p1 - pszBase58); if (!BN_mul(&bn, &bn, &bn58, pctx)) throw bignum_error("DecodeBase58 : BN_mul failed"); bn += bnChar; } // Get bignum as little endian data vector<unsigned char> vchTmp = bn.getvch(); // Trim off sign byte if present if (vchTmp.size() >= 2 && vchTmp.end()[-1] == 0 && vchTmp.end()[-2] >= 0x80) vchTmp.erase(vchTmp.end()-1); // Restore leading zeros int nLeadingZeros = 0; for (const char* p = psz; *p == pszBase58[0]; p++) nLeadingZeros++; vchRet.assign(nLeadingZeros + vchTmp.size(), 0); // Convert little endian data to big endian reverse_copy(vchTmp.begin(), vchTmp.end(), vchRet.end() - vchTmp.size()); return true; }
static bool verify(const CBigNum& bignum, const CScriptNum& scriptnum) { return bignum.getvch() == scriptnum.getvch() && bignum.getint() == scriptnum.getint(); }
bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, const CTransaction& txTo, unsigned int nIn, int nHashType) { CAutoBN_CTX pctx; CScript::const_iterator pc = script.begin(); CScript::const_iterator pend = script.end(); CScript::const_iterator pbegincodehash = script.begin(); opcodetype opcode; valtype vchPushValue; vector<bool> vfExec; vector<valtype> altstack; if (script.size() > 10000) return false; int nOpCount = 0; try { while (pc < pend) { bool fExec = !count(vfExec.begin(), vfExec.end(), false); // // Read instruction // if (!script.GetOp(pc, opcode, vchPushValue)) return false; if (vchPushValue.size() > 520) return false; if (opcode > OP_16 && ++nOpCount > 201) return false; if (opcode == OP_CAT || opcode == OP_SUBSTR || opcode == OP_LEFT || opcode == OP_RIGHT || opcode == OP_INVERT || opcode == OP_AND || opcode == OP_OR || opcode == OP_XOR || opcode == OP_2MUL || opcode == OP_2DIV || opcode == OP_MUL || opcode == OP_DIV || opcode == OP_MOD || opcode == OP_LSHIFT || opcode == OP_RSHIFT) return false; if (fExec && 0 <= opcode && opcode <= OP_PUSHDATA4) stack.push_back(vchPushValue); else if (fExec || (OP_IF <= opcode && opcode <= OP_ENDIF)) switch (opcode) { // // Push value // case OP_1NEGATE: case OP_1: case OP_2: case OP_3: case OP_4: case OP_5: case OP_6: case OP_7: case OP_8: case OP_9: case OP_10: case OP_11: case OP_12: case OP_13: case OP_14: case OP_15: case OP_16: { // ( -- value) CBigNum bn((int)opcode - (int)(OP_1 - 1)); stack.push_back(bn.getvch()); } break; // // Control // case OP_NOP: case OP_NOP1: case OP_NOP2: case OP_NOP3: case OP_NOP4: case OP_NOP5: case OP_NOP6: case OP_NOP7: case OP_NOP8: case OP_NOP9: case OP_NOP10: break; case OP_IF: case OP_NOTIF: { // <expression> if [statements] [else [statements]] endif bool fValue = false; if (fExec) { if (stack.size() < 1) return false; valtype& vch = stacktop(-1); fValue = CastToBool(vch); if (opcode == OP_NOTIF) fValue = !fValue; popstack(stack); } vfExec.push_back(fValue); } break; case OP_ELSE: { if (vfExec.empty()) return false; vfExec.back() = !vfExec.back(); } break; case OP_ENDIF: { if (vfExec.empty()) return false; vfExec.pop_back(); } break; case OP_VERIFY: { // (true -- ) or // (false -- false) and return if (stack.size() < 1) return false; bool fValue = CastToBool(stacktop(-1)); if (fValue) popstack(stack); else return false; } break; case OP_RETURN: { return false; } break; // // Stack ops // case OP_TOALTSTACK: { if (stack.size() < 1) return false; altstack.push_back(stacktop(-1)); popstack(stack); } break; case OP_FROMALTSTACK: { if (altstack.size() < 1) return false; stack.push_back(altstacktop(-1)); popstack(altstack); } break; case OP_2DROP: { // (x1 x2 -- ) if (stack.size() < 2) return false; popstack(stack); popstack(stack); } break; case OP_2DUP: { // (x1 x2 -- x1 x2 x1 x2) if (stack.size() < 2) return false; valtype vch1 = stacktop(-2); valtype vch2 = stacktop(-1); stack.push_back(vch1); stack.push_back(vch2); } break; case OP_3DUP: { // (x1 x2 x3 -- x1 x2 x3 x1 x2 x3) if (stack.size() < 3) return false; valtype vch1 = stacktop(-3); valtype vch2 = stacktop(-2); valtype vch3 = stacktop(-1); stack.push_back(vch1); stack.push_back(vch2); stack.push_back(vch3); } break; case OP_2OVER: { // (x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2) if (stack.size() < 4) return false; valtype vch1 = stacktop(-4); valtype vch2 = stacktop(-3); stack.push_back(vch1); stack.push_back(vch2); } break; case OP_2ROT: { // (x1 x2 x3 x4 x5 x6 -- x3 x4 x5 x6 x1 x2) if (stack.size() < 6) return false; valtype vch1 = stacktop(-6); valtype vch2 = stacktop(-5); stack.erase(stack.end()-6, stack.end()-4); stack.push_back(vch1); stack.push_back(vch2); } break; case OP_2SWAP: { // (x1 x2 x3 x4 -- x3 x4 x1 x2) if (stack.size() < 4) return false; swap(stacktop(-4), stacktop(-2)); swap(stacktop(-3), stacktop(-1)); } break; case OP_IFDUP: { // (x - 0 | x x) if (stack.size() < 1) return false; valtype vch = stacktop(-1); if (CastToBool(vch)) stack.push_back(vch); } break; case OP_DEPTH: { // -- stacksize CBigNum bn(stack.size()); stack.push_back(bn.getvch()); } break; case OP_DROP: { // (x -- ) if (stack.size() < 1) return false; popstack(stack); } break; case OP_DUP: { // (x -- x x) if (stack.size() < 1) return false; valtype vch = stacktop(-1); stack.push_back(vch); } break; case OP_NIP: { // (x1 x2 -- x2) if (stack.size() < 2) return false; stack.erase(stack.end() - 2); } break; case OP_OVER: { // (x1 x2 -- x1 x2 x1) if (stack.size() < 2) return false; valtype vch = stacktop(-2); stack.push_back(vch); } break; case OP_PICK: case OP_ROLL: { // (xn ... x2 x1 x0 n - xn ... x2 x1 x0 xn) // (xn ... x2 x1 x0 n - ... x2 x1 x0 xn) if (stack.size() < 2) return false; int n = CastToBigNum(stacktop(-1)).getint(); popstack(stack); if (n < 0 || n >= stack.size()) return false; valtype vch = stacktop(-n-1); if (opcode == OP_ROLL) stack.erase(stack.end()-n-1); stack.push_back(vch); } break; case OP_ROT: { // (x1 x2 x3 -- x2 x3 x1) // x2 x1 x3 after first swap // x2 x3 x1 after second swap if (stack.size() < 3) return false; swap(stacktop(-3), stacktop(-2)); swap(stacktop(-2), stacktop(-1)); } break; case OP_SWAP: { // (x1 x2 -- x2 x1) if (stack.size() < 2) return false; swap(stacktop(-2), stacktop(-1)); } break; case OP_TUCK: { // (x1 x2 -- x2 x1 x2) if (stack.size() < 2) return false; valtype vch = stacktop(-1); stack.insert(stack.end()-2, vch); } break; // // Splice ops // case OP_CAT: { // (x1 x2 -- out) if (stack.size() < 2) return false; valtype& vch1 = stacktop(-2); valtype& vch2 = stacktop(-1); vch1.insert(vch1.end(), vch2.begin(), vch2.end()); popstack(stack); if (stacktop(-1).size() > 520) return false; } break; case OP_SUBSTR: { // (in begin size -- out) if (stack.size() < 3) return false; valtype& vch = stacktop(-3); int nBegin = CastToBigNum(stacktop(-2)).getint(); int nEnd = nBegin + CastToBigNum(stacktop(-1)).getint(); if (nBegin < 0 || nEnd < nBegin) return false; if (nBegin > vch.size()) nBegin = vch.size(); if (nEnd > vch.size()) nEnd = vch.size(); vch.erase(vch.begin() + nEnd, vch.end()); vch.erase(vch.begin(), vch.begin() + nBegin); popstack(stack); popstack(stack); } break; case OP_LEFT: case OP_RIGHT: { // (in size -- out) if (stack.size() < 2) return false; valtype& vch = stacktop(-2); int nSize = CastToBigNum(stacktop(-1)).getint(); if (nSize < 0) return false; if (nSize > vch.size()) nSize = vch.size(); if (opcode == OP_LEFT) vch.erase(vch.begin() + nSize, vch.end()); else vch.erase(vch.begin(), vch.end() - nSize); popstack(stack); } break; case OP_SIZE: { // (in -- in size) if (stack.size() < 1) return false; CBigNum bn(stacktop(-1).size()); stack.push_back(bn.getvch()); } break; // // Bitwise logic // case OP_INVERT: { // (in - out) if (stack.size() < 1) return false; valtype& vch = stacktop(-1); for (int i = 0; i < vch.size(); i++) vch[i] = ~vch[i]; } break; case OP_AND: case OP_OR: case OP_XOR: { // (x1 x2 - out) if (stack.size() < 2) return false; valtype& vch1 = stacktop(-2); valtype& vch2 = stacktop(-1); MakeSameSize(vch1, vch2); if (opcode == OP_AND) { for (int i = 0; i < vch1.size(); i++) vch1[i] &= vch2[i]; } else if (opcode == OP_OR) { for (int i = 0; i < vch1.size(); i++) vch1[i] |= vch2[i]; } else if (opcode == OP_XOR) { for (int i = 0; i < vch1.size(); i++) vch1[i] ^= vch2[i]; } popstack(stack); } break; case OP_EQUAL: case OP_EQUALVERIFY: //case OP_NOTEQUAL: // use OP_NUMNOTEQUAL { // (x1 x2 - bool) if (stack.size() < 2) return false; valtype& vch1 = stacktop(-2); valtype& vch2 = stacktop(-1); bool fEqual = (vch1 == vch2); // OP_NOTEQUAL is disabled because it would be too easy to say // something like n != 1 and have some wiseguy pass in 1 with extra // zero bytes after it (numerically, 0x01 == 0x0001 == 0x000001) //if (opcode == OP_NOTEQUAL) // fEqual = !fEqual; popstack(stack); popstack(stack); stack.push_back(fEqual ? vchTrue : vchFalse); if (opcode == OP_EQUALVERIFY) { if (fEqual) popstack(stack); else return false; } } break; // // Numeric // case OP_1ADD: case OP_1SUB: case OP_2MUL: case OP_2DIV: case OP_NEGATE: case OP_ABS: case OP_NOT: case OP_0NOTEQUAL: { // (in -- out) if (stack.size() < 1) return false; CBigNum bn = CastToBigNum(stacktop(-1)); switch (opcode) { case OP_1ADD: bn += bnOne; break; case OP_1SUB: bn -= bnOne; break; case OP_2MUL: bn <<= 1; break; case OP_2DIV: bn >>= 1; break; case OP_NEGATE: bn = -bn; break; case OP_ABS: if (bn < bnZero) bn = -bn; break; case OP_NOT: bn = (bn == bnZero); break; case OP_0NOTEQUAL: bn = (bn != bnZero); break; default: assert(!"invalid opcode"); break; } popstack(stack); stack.push_back(bn.getvch()); } break; case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: case OP_MOD: case OP_LSHIFT: case OP_RSHIFT: case OP_BOOLAND: case OP_BOOLOR: case OP_NUMEQUAL: case OP_NUMEQUALVERIFY: case OP_NUMNOTEQUAL: case OP_LESSTHAN: case OP_GREATERTHAN: case OP_LESSTHANOREQUAL: case OP_GREATERTHANOREQUAL: case OP_MIN: case OP_MAX: { // (x1 x2 -- out) if (stack.size() < 2) return false; CBigNum bn1 = CastToBigNum(stacktop(-2)); CBigNum bn2 = CastToBigNum(stacktop(-1)); CBigNum bn; switch (opcode) { case OP_ADD: bn = bn1 + bn2; break; case OP_SUB: bn = bn1 - bn2; break; case OP_MUL: if (!BN_mul(&bn, &bn1, &bn2, pctx)) return false; break; case OP_DIV: if (!BN_div(&bn, NULL, &bn1, &bn2, pctx)) return false; break; case OP_MOD: if (!BN_mod(&bn, &bn1, &bn2, pctx)) return false; break; case OP_LSHIFT: if (bn2 < bnZero || bn2 > CBigNum(2048)) return false; bn = bn1 << bn2.getulong(); break; case OP_RSHIFT: if (bn2 < bnZero || bn2 > CBigNum(2048)) return false; bn = bn1 >> bn2.getulong(); break; case OP_BOOLAND: bn = (bn1 != bnZero && bn2 != bnZero); break; case OP_BOOLOR: bn = (bn1 != bnZero || bn2 != bnZero); break; case OP_NUMEQUAL: bn = (bn1 == bn2); break; case OP_NUMEQUALVERIFY: bn = (bn1 == bn2); break; case OP_NUMNOTEQUAL: bn = (bn1 != bn2); break; case OP_LESSTHAN: bn = (bn1 < bn2); break; case OP_GREATERTHAN: bn = (bn1 > bn2); break; case OP_LESSTHANOREQUAL: bn = (bn1 <= bn2); break; case OP_GREATERTHANOREQUAL: bn = (bn1 >= bn2); break; case OP_MIN: bn = (bn1 < bn2 ? bn1 : bn2); break; case OP_MAX: bn = (bn1 > bn2 ? bn1 : bn2); break; default: assert(!"invalid opcode"); break; } popstack(stack); popstack(stack); stack.push_back(bn.getvch()); if (opcode == OP_NUMEQUALVERIFY) { if (CastToBool(stacktop(-1))) popstack(stack); else return false; } } break; case OP_WITHIN: { // (x min max -- out) if (stack.size() < 3) return false; CBigNum bn1 = CastToBigNum(stacktop(-3)); CBigNum bn2 = CastToBigNum(stacktop(-2)); CBigNum bn3 = CastToBigNum(stacktop(-1)); bool fValue = (bn2 <= bn1 && bn1 < bn3); popstack(stack); popstack(stack); popstack(stack); stack.push_back(fValue ? vchTrue : vchFalse); } break; // // Crypto // case OP_RIPEMD160: case OP_SHA1: case OP_SHA256: case OP_HASH160: case OP_HASH256: { // (in -- hash) if (stack.size() < 1) return false; valtype& vch = stacktop(-1); valtype vchHash((opcode == OP_RIPEMD160 || opcode == OP_SHA1 || opcode == OP_HASH160) ? 20 : 32); if (opcode == OP_RIPEMD160) RIPEMD160(&vch[0], vch.size(), &vchHash[0]); else if (opcode == OP_SHA1) SHA1(&vch[0], vch.size(), &vchHash[0]); else if (opcode == OP_SHA256) SHA256(&vch[0], vch.size(), &vchHash[0]); else if (opcode == OP_HASH160) { uint160 hash160 = Hash160(vch); memcpy(&vchHash[0], &hash160, sizeof(hash160)); } else if (opcode == OP_HASH256) { uint256 hash = Hash(vch.begin(), vch.end()); memcpy(&vchHash[0], &hash, sizeof(hash)); } popstack(stack); stack.push_back(vchHash); } break; case OP_CODESEPARATOR: { // Hash starts after the code separator pbegincodehash = pc; } break; case OP_CHECKSIG: case OP_CHECKSIGVERIFY: { // (sig pubkey -- bool) if (stack.size() < 2) return false; valtype& vchSig = stacktop(-2); valtype& vchPubKey = stacktop(-1); ////// debug print //PrintHex(vchSig.begin(), vchSig.end(), "sig: %s\n"); //PrintHex(vchPubKey.begin(), vchPubKey.end(), "pubkey: %s\n"); // Subset of script starting at the most recent codeseparator CScript scriptCode(pbegincodehash, pend); // Drop the signature, since there's no way for a signature to sign itself scriptCode.FindAndDelete(CScript(vchSig)); bool fSuccess = CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType); popstack(stack); popstack(stack); stack.push_back(fSuccess ? vchTrue : vchFalse); if (opcode == OP_CHECKSIGVERIFY) { if (fSuccess) popstack(stack); else return false; } } break; case OP_CHECKMULTISIG: case OP_CHECKMULTISIGVERIFY: { // ([sig ...] num_of_signatures [pubkey ...] num_of_pubkeys -- bool) int i = 1; if (stack.size() < i) return false; int nKeysCount = CastToBigNum(stacktop(-i)).getint(); if (nKeysCount < 0 || nKeysCount > 20) return false; nOpCount += nKeysCount; if (nOpCount > 201) return false; int ikey = ++i; i += nKeysCount; if (stack.size() < i) return false; int nSigsCount = CastToBigNum(stacktop(-i)).getint(); if (nSigsCount < 0 || nSigsCount > nKeysCount) return false; int isig = ++i; i += nSigsCount; if (stack.size() < i) return false; // Subset of script starting at the most recent codeseparator CScript scriptCode(pbegincodehash, pend); // Drop the signatures, since there's no way for a signature to sign itself for (int k = 0; k < nSigsCount; k++) { valtype& vchSig = stacktop(-isig-k); scriptCode.FindAndDelete(CScript(vchSig)); } bool fSuccess = true; while (fSuccess && nSigsCount > 0) { valtype& vchSig = stacktop(-isig); valtype& vchPubKey = stacktop(-ikey); // Check signature if (CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType)) { isig++; nSigsCount--; } ikey++; nKeysCount--; // If there are more signatures left than keys left, // then too many signatures have failed if (nSigsCount > nKeysCount) fSuccess = false; } while (i-- > 0) popstack(stack); stack.push_back(fSuccess ? vchTrue : vchFalse); if (opcode == OP_CHECKMULTISIGVERIFY) { if (fSuccess) popstack(stack); else return false; } } break; default: return false; } // Size limits if (stack.size() + altstack.size() > 1000) return false; } } catch (...) { return false; } if (!vfExec.empty()) return false; return true; }
bool BitcoinMiner2_mineProbableChain(primecoinBlock_t* block, mpz_class& mpzFixedMultiplier, bool& fNewBlock, unsigned int& nTriedMultiplier, unsigned int& nProbableChainLength, unsigned int& nTests, unsigned int& nPrimesHit, sint32 threadIndex, mpz_class& mpzHash, unsigned int nPrimorialMultiplier) { mpz_class mpzChainOrigin; mpz_class mpzFinalFixedMultiplier = mpzFixedMultiplier * mpzHash; mpz_class mpzTemp; uint32 nTime = GetTickCount(); cSieve_prepare(mpzFinalFixedMultiplier, block->nBits>>24); nTime = GetTickCount()-nTime; //printf("cSieve prep time: %d\n", nTime); unsigned int nPrimorialSeq = 0; while (vPrimes[nPrimorialSeq + 1] <= nPrimorialMultiplier) nPrimorialSeq++; // Allocate GMP variables for primality tests CPrimalityTestParams testParams(block->nBits, nPrimorialSeq); { unsigned long lDivisor = 1; unsigned int i; testParams.vFastDivSeq.push_back(nPrimorialSeq); for (i = 1; i <= nFastDivPrimes; i++) { // Multiply primes together until the result won't fit an unsigned long if (lDivisor < ULONG_MAX / vPrimes[nPrimorialSeq + i]) lDivisor *= vPrimes[nPrimorialSeq + i]; else { testParams.vFastDivisors.push_back(lDivisor); testParams.vFastDivSeq.push_back(nPrimorialSeq + i); lDivisor = 1; } } // Finish off by multiplying as many primes as possible while (lDivisor < ULONG_MAX / vPrimes[nPrimorialSeq + i]) { lDivisor *= vPrimes[nPrimorialSeq + i]; i++; } testParams.vFastDivisors.push_back(lDivisor); testParams.vFastDivSeq.push_back(nPrimorialSeq + i); testParams.nFastDivisorsSize = testParams.vFastDivisors.size(); } // References to counters; unsigned int& nChainLengthCunningham1 = testParams.nChainLengthCunningham1; unsigned int& nChainLengthCunningham2 = testParams.nChainLengthCunningham2; unsigned int& nChainLengthBiTwin = testParams.nChainLengthBiTwin; uint32 debugStats_primes = 0; uint32 debugStats_multipliersTested = 0; while( block->serverData.blockHeight == jhMiner_getCurrentWorkBlockHeight(block->threadIndex) ) { uint32 sieveFlags; uint32 multiplier = cSieve_findNextMultiplier(&sieveFlags); if( multiplier == 0 ) { // mix in next layer //printf("Layer finished [%d]\n", cSieve->currentSieveLayerIdx); if( cSieve_sieveNextLayer() == false ) break; mpzFinalFixedMultiplier = cSieve->mpzFixedMultiplier; //printf("[%02d] debugStats_multipliersTested: %d\n", cSieve->currentSieveLayerIdx, debugStats_multipliersTested); //printf("[%02d] debugStats_primes: %d\n", cSieve->currentSieveLayerIdx, debugStats_primes); //double primality = (double)debugStats_primes / (double)debugStats_multipliersTested; //printf("[%02d] debugStats_primality: %lf\n", cSieve->currentSieveLayerIdx, primality); debugStats_primes = 0; debugStats_multipliersTested = 0; continue; } //// test for sieve bugs C1 //if( (sieveFlags&SIEVE_FLAG_C1_COMPOSITE)==0 && (rand()%10)==0 ) //{ // // test c1 // for(uint32 lt=0; lt<cSieve->chainLength; lt++) // { // uint32 aMult = 1<<lt; // mpzChainOrigin = mpzFinalFixedMultiplier * multiplier * aMult - 1; // for(uint32 f=0; f<cSieve->numPrimeFactors; f++) // { // uint32 mod = mpz_mod_ui(mpzTemp.get_mpz_t(), mpzChainOrigin.get_mpz_t(), vPrimes[f]); // if( mod == 0 ) // printf("c1 div by %d possible\n", vPrimes[f]);//__debugbreak(); // } // } //} //// test for sieve bugs C2 //if( (sieveFlags&SIEVE_FLAG_C2_COMPOSITE)==0 && (rand()%10)==0 ) //{ // // test c1 // for(uint32 lt=0; lt<cSieve->chainLength; lt++) // { // uint32 aMult = 1<<lt; // mpzChainOrigin = mpzFinalFixedMultiplier * multiplier * aMult + 1; // for(uint32 f=0; f<cSieve->numPrimeFactors; f++) // { // uint32 mod = mpz_mod_ui(mpzTemp.get_mpz_t(), mpzChainOrigin.get_mpz_t(), vPrimes[f]); // if( mod == 0 ) // printf("c2 div by %d possible\n", vPrimes[f]);//__debugbreak(); // } // } //} // test for sieve bugs BT //if( (sieveFlags&SIEVE_FLAG_BT_COMPOSITE)==0 ) //{ // // test c1 // mpzChainOrigin = mpzFinalFixedMultiplier * multiplier + 1; // for(uint32 f=0; f<cSieve->numPrimeFactors; f++) // { // uint32 mod = mpz_mod_ui(mpzTemp.get_mpz_t(), mpzChainOrigin.get_mpz_t(), vPrimes[f]); // if( mod == 0 ) // printf("bt-c2 div by %d possible\n", vPrimes[f]); // } // // test c2 // mpzChainOrigin = mpzFinalFixedMultiplier * multiplier - 1; // for(uint32 f=0; f<cSieve->numPrimeFactors; f++) // { // uint32 mod = mpz_mod_ui(mpzTemp.get_mpz_t(), mpzChainOrigin.get_mpz_t(), vPrimes[f]); // if( mod == 0 ) // printf("bt-c2 div by %d possible\n", vPrimes[f]); // } //} //mpzChainOrigin = mpzFinalFixedMultiplier * multiplier; mpz_mul_ui(mpzChainOrigin.get_mpz_t(), mpzFinalFixedMultiplier.get_mpz_t(), multiplier); nChainLengthCunningham1 = 0; nChainLengthCunningham2 = 0; nChainLengthBiTwin = 0; bool canSubmitAsShare = ProbablePrimeChainTestFast2(mpzChainOrigin, testParams, sieveFlags, multiplier); nProbableChainLength = max(max(nChainLengthCunningham1, nChainLengthCunningham2), nChainLengthBiTwin); if( nProbableChainLength >= 0x01000000 ) debugStats_primes++; debugStats_multipliersTested++; //bool canSubmitAsShare = ProbablePrimeChainTestFast(mpzChainOrigin, testParams); //CBigNum bnChainOrigin; //bnChainOrigin.SetHex(mpzChainOrigin.get_str(16)); //bool canSubmitAsShare = ProbablePrimeChainTestBN(bnChainOrigin, block->serverData.nBitsForShare, false, nChainLengthCunningham1, nChainLengthCunningham2, nChainLengthBiTwin); if( nProbableChainLength >= 0x04000000 ) { sint32 chainDif = (nProbableChainLength>>24) - 7; primeStats.nChainHit += pow(8, (float)chainDif); //primeStats.nChainHit += pow(8, ((float)((double)nProbableChainLength / (double)0x1000000))-7.0); //primeStats.nChainHit += pow(8, floor((float)((double)nProbableChainLength / (double)0x1000000)) - 7); nTests = 0; primeStats.fourChainCount ++; if (nProbableChainLength >= 0x5000000) { primeStats.fiveChainCount ++; if (nProbableChainLength >= 0x6000000) { primeStats.sixChainCount ++; if (nProbableChainLength >= 0x7000000) primeStats.sevenChainCount ++; } } } //if( nBitsGen >= 0x03000000 ) // printf("%08X\n", nBitsGen); primeStats.primeChainsFound++; //if( nProbableChainLength > 0x03000000 ) // primeStats.qualityPrimesFound++; if( nProbableChainLength > primeStats.bestPrimeChainDifficulty ) primeStats.bestPrimeChainDifficulty = nProbableChainLength; if(nProbableChainLength >= block->serverData.nBitsForShare) { // note: mpzPrimeChainMultiplier does not include the blockHash multiplier mpz_div(block->mpzPrimeChainMultiplier.get_mpz_t(), mpzChainOrigin.get_mpz_t(), mpzHash.get_mpz_t()); //mpz_lsh(block->mpzPrimeChainMultiplier.get_mpz_t(), mpzFixedMultiplier.get_mpz_t(), multiplier); // update server data block->serverData.client_shareBits = nProbableChainLength; // generate block raw data uint8 blockRawData[256] = {0}; memcpy(blockRawData, block, 80); uint32 writeIndex = 80; sint32 lengthBN = 0; CBigNum bnPrimeChainMultiplier; bnPrimeChainMultiplier.SetHex(block->mpzPrimeChainMultiplier.get_str(16)); std::vector<unsigned char> bnSerializeData = bnPrimeChainMultiplier.getvch(); lengthBN = bnSerializeData.size(); *(uint8*)(blockRawData+writeIndex) = (uint8)lengthBN; // varInt (we assume it always has a size low enough for 1 byte) writeIndex += 1; memcpy(blockRawData+writeIndex, &bnSerializeData[0], lengthBN); writeIndex += lengthBN; // switch endianness for(uint32 f=0; f<256/4; f++) { *(uint32*)(blockRawData+f*4) = _swapEndianessU32(*(uint32*)(blockRawData+f*4)); } time_t now = time(0); struct tm * timeinfo; timeinfo = localtime (&now); char sNow [80]; strftime (sNow, 80, "%x - %X",timeinfo); printf("%s - SHARE FOUND !!! (Th#: %u Multiplier: %d Layer: %d) --- DIFF: %f %s %s\n", sNow, threadIndex, multiplier, cSieve->currentSieveLayerIdx, (float)((double)nProbableChainLength / (double)0x1000000), nProbableChainLength >= 0x6000000 ? ">6":"", nProbableChainLength >= 0x7000000 ? ">7":""); // submit this share if (jhMiner_pushShare_primecoin(blockRawData, block)) primeStats.foundShareCount ++; //printf("Probable prime chain found for block=%s!!\n Target: %s\n Length: (%s %s %s)\n", block.GetHash().GetHex().c_str(),TargetToString(block.nBits).c_str(), TargetToString(nChainLengthCunningham1).c_str(), TargetToString(nChainLengthCunningham2).c_str(), TargetToString(nChainLengthBiTwin).c_str()); //nProbableChainLength = max(max(nChainLengthCunningham1, nChainLengthCunningham2), nChainLengthBiTwin); // since we are using C structs here we have to make sure the memory for the CBigNum in the block is freed again //delete *psieve; //*psieve = NULL; //block->bnPrimeChainMultiplier = NULL; RtlZeroMemory(blockRawData, 256); //delete *psieve; //*psieve = NULL; // dont quit if we find a share, there could be other shares in the remaining prime candidates nTests = 0; // tehere is a good chance to find more shares so search a litle more. //block->nonce++; //return true; //break; //if (multipleShare) } }
/* bool Evaluator::operator()(const Script& script, const Script& tmpl) { _begin = script.begin(); _current = script.begin(); _end = script.end(); Script::const_iterator current = tmpl.begin(); // step through the script and template - } */ boost::tribool Evaluator::eval(opcodetype opcode) { switch (opcode) { // Push value case OP_1NEGATE: case OP_1: case OP_2: case OP_3: case OP_4: case OP_5: case OP_6: case OP_7: case OP_8: case OP_9: case OP_10: case OP_11: case OP_12: case OP_13: case OP_14: case OP_15: case OP_16: { // ( -- value) CBigNum bn((int)opcode - (int)(OP_1 - 1)); _stack.push_back(bn.getvch()); break; } // Control case OP_NOP: case OP_NOP1: case OP_NOP2: case OP_NOP3: case OP_NOP4: case OP_NOP5: case OP_NOP6: case OP_NOP7: case OP_NOP8: case OP_NOP9: case OP_NOP10: break; case OP_IF: case OP_NOTIF: { // <expression> if [statements] [else [statements]] endif bool fValue = false; if (_exec) { if (_stack.size() < 1) return false; Value& vch = top(-1); fValue = CastToBool(vch); if (opcode == OP_NOTIF) fValue = !fValue; pop(_stack); } _exec_stack.push_back(fValue); break; } case OP_ELSE: { if (_exec_stack.empty()) return false; _exec_stack.back() = !_exec_stack.back(); break; } case OP_ENDIF: { if (_exec_stack.empty()) return false; _exec_stack.pop_back(); break; } case OP_VERIFY: { // (true -- ) or // (false -- false) and return if (_stack.size() < 1) return false; bool fValue = CastToBool(top(-1)); if (fValue) pop(_stack); else return false; break; } case OP_RETURN: { return false; break; } // Stack ops case OP_TOALTSTACK: { if (_stack.size() < 1) return false; _alt_stack.push_back(top(-1)); pop(_stack); break; } case OP_FROMALTSTACK: { if (_alt_stack.size() < 1) return false; _stack.push_back(alttop(-1)); pop(_alt_stack); break; } case OP_2DROP: { // (x1 x2 -- ) if (_stack.size() < 2) return false; pop(_stack); pop(_stack); break; } case OP_2DUP: { // (x1 x2 -- x1 x2 x1 x2) if (_stack.size() < 2) return false; Value vch1 = top(-2); Value vch2 = top(-1); _stack.push_back(vch1); _stack.push_back(vch2); break; } case OP_3DUP: { // (x1 x2 x3 -- x1 x2 x3 x1 x2 x3) if (_stack.size() < 3) return false; Value vch1 = top(-3); Value vch2 = top(-2); Value vch3 = top(-1); _stack.push_back(vch1); _stack.push_back(vch2); _stack.push_back(vch3); break; } case OP_2OVER: { // (x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2) if (_stack.size() < 4) return false; Value vch1 = top(-4); Value vch2 = top(-3); _stack.push_back(vch1); _stack.push_back(vch2); break; } case OP_2ROT: { // (x1 x2 x3 x4 x5 x6 -- x3 x4 x5 x6 x1 x2) if (_stack.size() < 6) return false; Value vch1 = top(-6); Value vch2 = top(-5); _stack.erase(_stack.end()-6, _stack.end()-4); _stack.push_back(vch1); _stack.push_back(vch2); break; } case OP_2SWAP: { // (x1 x2 x3 x4 -- x3 x4 x1 x2) if (_stack.size() < 4) return false; swap(top(-4), top(-2)); swap(top(-3), top(-1)); break; } case OP_IFDUP: { // (x - 0 | x x) if (_stack.size() < 1) return false; Value vch = top(-1); if (CastToBool(vch)) _stack.push_back(vch); break; } case OP_DEPTH: { // -- stacksize CBigNum bn((uint64_t)_stack.size()); _stack.push_back(bn.getvch()); break; } case OP_DROP: { // (x -- ) if (_stack.size() < 1) return false; pop(_stack); break; } case OP_DUP: { // (x -- x x) if (_stack.size() < 1) return false; Value vch = top(-1); _stack.push_back(vch); break; } case OP_NIP: { // (x1 x2 -- x2) if (_stack.size() < 2) return false; _stack.erase(_stack.end() - 2); break; } case OP_OVER: { // (x1 x2 -- x1 x2 x1) if (_stack.size() < 2) return false; Value vch = top(-2); _stack.push_back(vch); break; } case OP_PICK: case OP_ROLL: { // (xn ... x2 x1 x0 n - xn ... x2 x1 x0 xn) // (xn ... x2 x1 x0 n - ... x2 x1 x0 xn) if (_stack.size() < 2) return false; int n = CastToBigNum(top(-1)).getint(); pop(_stack); if (n < 0 || (unsigned int)n >= _stack.size()) return false; Value vch = top(-n-1); if (opcode == OP_ROLL) _stack.erase(_stack.end()-n-1); _stack.push_back(vch); break; } case OP_ROT: { // (x1 x2 x3 -- x2 x3 x1) // x2 x1 x3 after first swap // x2 x3 x1 after second swap if (_stack.size() < 3) return false; swap(top(-3), top(-2)); swap(top(-2), top(-1)); break; } case OP_SWAP: { // (x1 x2 -- x2 x1) if (_stack.size() < 2) return false; swap(top(-2), top(-1)); break; } case OP_TUCK: { // (x1 x2 -- x2 x1 x2) if (_stack.size() < 2) return false; Value vch = top(-1); _stack.insert(_stack.end()-2, vch); break; } // // Splice ops // case OP_CAT: { // (x1 x2 -- out) if (_stack.size() < 2) return false; Value& vch1 = top(-2); Value& vch2 = top(-1); vch1.insert(vch1.end(), vch2.begin(), vch2.end()); pop(_stack); if (top(-1).size() > MAX_SCRIPT_ELEMENT_SIZE) return false; break; } case OP_SUBSTR: { // (in begin size -- out) if (_stack.size() < 3) return false; Value& vch = top(-3); int nBegin = CastToBigNum(top(-2)).getint(); int nEnd = nBegin + CastToBigNum(top(-1)).getint(); if (nBegin < 0 || nEnd < nBegin) return false; if ((unsigned int)nBegin > vch.size()) nBegin = vch.size(); if ((unsigned int)nEnd > vch.size()) nEnd = vch.size(); vch.erase(vch.begin() + nEnd, vch.end()); vch.erase(vch.begin(), vch.begin() + nBegin); pop(_stack); pop(_stack); break; } case OP_LEFT: case OP_RIGHT: { // (in size -- out) if (_stack.size() < 2) return false; Value& vch = top(-2); int nSize = CastToBigNum(top(-1)).getint(); if (nSize < 0) return false; if ((unsigned int)nSize > vch.size()) nSize = vch.size(); if (opcode == OP_LEFT) vch.erase(vch.begin() + nSize, vch.end()); else vch.erase(vch.begin(), vch.end() - nSize); pop(_stack); break; } case OP_SIZE: { // (in -- in size) if (_stack.size() < 1) return false; CBigNum bn((uint64_t)top(-1).size()); _stack.push_back(bn.getvch()); break; } // Bitwise logic case OP_INVERT: { // (in - out) if (_stack.size() < 1) return false; Value& vch = top(-1); for (unsigned int i = 0; i < vch.size(); i++) vch[i] = ~vch[i]; break; } case OP_AND: case OP_OR: case OP_XOR: { // (x1 x2 - out) if (_stack.size() < 2) return false; Value& vch1 = top(-2); Value& vch2 = top(-1); MakeSameSize(vch1, vch2); if (opcode == OP_AND) { for (unsigned int i = 0; i < vch1.size(); i++) vch1[i] &= vch2[i]; } else if (opcode == OP_OR) { for (unsigned int i = 0; i < vch1.size(); i++) vch1[i] |= vch2[i]; } else if (opcode == OP_XOR) { for (unsigned int i = 0; i < vch1.size(); i++) vch1[i] ^= vch2[i]; } pop(_stack); break; } case OP_EQUAL: //case OP_NOTEQUAL: // use OP_NUMNOTEQUAL case OP_EQUALVERIFY: { // (x1 x2 - bool) if (_stack.size() < 2) return false; Value& vch1 = top(-2); Value& vch2 = top(-1); bool fEqual = (vch1 == vch2); // OP_NOTEQUAL is disabled because it would be too easy to say // something like n != 1 and have some wiseguy pass in 1 with extra // zero bytes after it (numerically, 0x01 == 0x0001 == 0x000001) //if (opcode == OP_NOTEQUAL) // fEqual = !fEqual; pop(_stack); pop(_stack); _stack.push_back(fEqual ? vchTrue : vchFalse); if (opcode == OP_EQUALVERIFY) { if (fEqual) pop(_stack); else return false; } break; } // Numeric case OP_1ADD: case OP_1SUB: case OP_2MUL: case OP_2DIV: case OP_NEGATE: case OP_ABS: case OP_NOT: case OP_0NOTEQUAL: { // (in -- out) if (_stack.size() < 1) return false; CBigNum bn = CastToBigNum(top(-1)); switch (opcode) { case OP_1ADD: bn += bnOne; break; case OP_1SUB: bn -= bnOne; break; case OP_2MUL: bn <<= 1; break; case OP_2DIV: bn >>= 1; break; case OP_NEGATE: bn = -bn; break; case OP_ABS: if (bn < bnZero) bn = -bn; break; case OP_NOT: bn = (bn == bnZero); break; case OP_0NOTEQUAL: bn = (bn != bnZero); break; default: assert(!"invalid opcode"); break; } pop(_stack); _stack.push_back(bn.getvch()); break; } case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: case OP_MOD: case OP_LSHIFT: case OP_RSHIFT: case OP_BOOLAND: case OP_BOOLOR: case OP_NUMEQUAL: case OP_NUMEQUALVERIFY: case OP_NUMNOTEQUAL: case OP_LESSTHAN: case OP_GREATERTHAN: case OP_LESSTHANOREQUAL: case OP_GREATERTHANOREQUAL: case OP_MIN: case OP_MAX: { // (x1 x2 -- out) CAutoBN_CTX pctx; if (_stack.size() < 2) return false; CBigNum bn1 = CastToBigNum(top(-2)); CBigNum bn2 = CastToBigNum(top(-1)); CBigNum bn; switch (opcode) { case OP_ADD: bn = bn1 + bn2; break; case OP_SUB: bn = bn1 - bn2; break; case OP_MUL: if (!BN_mul(&bn, &bn1, &bn2, pctx)) return false; break; case OP_DIV: if (!BN_div(&bn, NULL, &bn1, &bn2, pctx)) return false; break; case OP_MOD: if (!BN_mod(&bn, &bn1, &bn2, pctx)) return false; break; case OP_LSHIFT: if (bn2 < bnZero || bn2 > CBigNum(2048)) return false; bn = bn1 << bn2.getulong(); break; case OP_RSHIFT: if (bn2 < bnZero || bn2 > CBigNum(2048)) return false; bn = bn1 >> bn2.getulong(); break; case OP_BOOLAND: bn = (bn1 != bnZero && bn2 != bnZero); break; case OP_BOOLOR: bn = (bn1 != bnZero || bn2 != bnZero); break; case OP_NUMEQUAL: bn = (bn1 == bn2); break; case OP_NUMEQUALVERIFY: bn = (bn1 == bn2); break; case OP_NUMNOTEQUAL: bn = (bn1 != bn2); break; case OP_LESSTHAN: bn = (bn1 < bn2); break; case OP_GREATERTHAN: bn = (bn1 > bn2); break; case OP_LESSTHANOREQUAL: bn = (bn1 <= bn2); break; case OP_GREATERTHANOREQUAL: bn = (bn1 >= bn2); break; case OP_MIN: bn = (bn1 < bn2 ? bn1 : bn2); break; case OP_MAX: bn = (bn1 > bn2 ? bn1 : bn2); break; default: assert(!"invalid opcode"); break; } pop(_stack); pop(_stack); _stack.push_back(bn.getvch()); if (opcode == OP_NUMEQUALVERIFY) { if (CastToBool(top(-1))) pop(_stack); else return false; } break; } case OP_WITHIN: { // (x min max -- out) if (_stack.size() < 3) return false; CBigNum bn1 = CastToBigNum(top(-3)); CBigNum bn2 = CastToBigNum(top(-2)); CBigNum bn3 = CastToBigNum(top(-1)); bool fValue = (bn2 <= bn1 && bn1 < bn3); pop(_stack); pop(_stack); pop(_stack); _stack.push_back(fValue ? vchTrue : vchFalse); break; } // Crypto case OP_RIPEMD160: case OP_SHA1: case OP_SHA256: case OP_HASH160: case OP_HASH256: { // (in -- hash) if (_stack.size() < 1) return false; Value& vch = top(-1); Value vchHash((opcode == OP_RIPEMD160 || opcode == OP_SHA1 || opcode == OP_HASH160) ? 20 : 32); if (opcode == OP_RIPEMD160) RIPEMD160(&vch[0], vch.size(), &vchHash[0]); else if (opcode == OP_SHA1) SHA1(&vch[0], vch.size(), &vchHash[0]); else if (opcode == OP_SHA256) SHA256(&vch[0], vch.size(), &vchHash[0]); else if (opcode == OP_HASH160) { uint160 hash160 = toPubKeyHash(vch); memcpy(&vchHash[0], &hash160, sizeof(hash160)); } else if (opcode == OP_HASH256) { uint256 hash = Hash(vch.begin(), vch.end()); memcpy(&vchHash[0], &hash, sizeof(hash)); } pop(_stack); _stack.push_back(vchHash); break; } default: break; } return indeterminate; }
bool DecodeBase58(const char* psz, std::vector<unsigned char>& vchRet) { CAutoBN_CTX pctx; vchRet.clear(); CBigNum bn58 = 58; CBigNum bn = 0; CBigNum bnChar; // Skip leading spaces. while (*psz && isspace(*psz)) psz++; // Skip and count leading '1's. int zeroes = 0; while (*psz == '1') { zeroes++; psz++; } // Convert big endian string to bignum for (const char* p = psz; *p; p++) { const char* p1 = strchr(pszBase58, *p); if (p1 == NULL) { while (isspace(*p)) p++; if (*p != '\0') return false; break; } bnChar.setulong(p1 - pszBase58); if (!BN_mul(&bn, &bn, &bn58, pctx)) throw bignum_error("DecodeBase58 : BN_mul failed"); bn += bnChar; } // Get bignum as little endian data std::vector<unsigned char> vchTmp = bn.getvch(); // Trim off sign byte if present if (vchTmp.size() >= 2 && vchTmp.end()[-1] == 0 && vchTmp.end()[-2] >= 0x80) vchTmp.erase(vchTmp.end()-1); // Restore leading zeros int nLeadingZeros = 0; for (const char* p = psz; *p == pszBase58[0]; p++) nLeadingZeros++; vchRet.assign(nLeadingZeros + vchTmp.size(), 0); // Convert little endian data to big endian reverse_copy(vchTmp.begin(), vchTmp.end(), vchRet.end() - vchTmp.size()); return true; // Allocate enough space in big-endian base256 representation. std::vector<unsigned char> b256(strlen(psz) * 733 / 1000 + 1); // log(58) / log(256), rounded up. // Process the characters. while (*psz && !isspace(*psz)) { // Decode base58 character const char *ch = strchr(pszBase58, *psz); if (ch == NULL) return false; // Apply "b256 = b256 * 58 + ch". int carry = ch - pszBase58; for (std::vector<unsigned char>::reverse_iterator it = b256.rbegin(); it != b256.rend(); it++) { carry += 58 * (*it); *it = carry % 256; carry /= 256; } assert(carry == 0); psz++; } // Skip trailing spaces. while (isspace(*psz)) psz++; if (*psz != 0) return false; // Skip leading zeroes in b256. std::vector<unsigned char>::iterator it = b256.begin(); while (it != b256.end() && *it == 0) it++; // Copy result into output vector. vchRet.reserve(zeroes + (b256.end() - it)); vchRet.assign(zeroes, 0x00); while (it != b256.end()) vchRet.push_back(*(it++)); return true; }