CryptoPP::ECP CryptoECDSA::Get_secp256k1_ECP(void) { static bool firstRun = true; static CryptoPP::Integer intN; static CryptoPP::Integer inta; static CryptoPP::Integer intb; static BinaryData N; static BinaryData a; static BinaryData b; if(firstRun) { firstRun = false; N = BinaryData::CreateFromHex( "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f"); a = BinaryData::CreateFromHex( "0000000000000000000000000000000000000000000000000000000000000000"); b = BinaryData::CreateFromHex( "0000000000000000000000000000000000000000000000000000000000000007"); intN.Decode( N.getPtr(), N.getSize(), UNSIGNED); inta.Decode( a.getPtr(), a.getSize(), UNSIGNED); intb.Decode( b.getPtr(), b.getSize(), UNSIGNED); } return CryptoPP::ECP(intN, inta, intb); }
bool CryptoECDSA::VerifyPublicKeyValid(SecureBinaryData const & pubKey65) { if(CRYPTO_DEBUG) { cout << "BinPub: " << pubKey65.toHexStr() << endl; } // Basically just copying the ParsePublicKey method, but without // the assert that would throw an error from C++ SecureBinaryData pubXbin(pubKey65.getSliceRef( 1,32)); SecureBinaryData pubYbin(pubKey65.getSliceRef(33,32)); CryptoPP::Integer pubX; CryptoPP::Integer pubY; pubX.Decode(pubXbin.getPtr(), pubXbin.getSize(), UNSIGNED); pubY.Decode(pubYbin.getPtr(), pubYbin.getSize(), UNSIGNED); BTC_ECPOINT publicPoint(pubX, pubY); // Initialize the public key with the ECP point just created BTC_PUBKEY cppPubKey; cppPubKey.Initialize(CryptoPP::ASN1::secp256k1(), publicPoint); // Validate the public key -- not sure why this needs a PRNG static BTC_PRNG prng; return cppPubKey.Validate(prng, 3); }
SecureBinaryData CryptoECDSA::InvMod(const SecureBinaryData& m) { static BinaryData N = BinaryData::CreateFromHex( "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141"); CryptoPP::Integer cppM; CryptoPP::Integer cppModulo; cppM.Decode(m.getPtr(), m.getSize(), UNSIGNED); cppModulo.Decode(N.getPtr(), N.getSize(), UNSIGNED); CryptoPP::Integer cppResult = cppM.InverseMod(cppModulo); SecureBinaryData result(32); cppResult.Encode(result.getPtr(), result.getSize(), UNSIGNED); return result; }
bool CryptoECDSA::ECVerifyPoint(BinaryData const & x, BinaryData const & y) { BTC_PUBKEY cppPubKey; CryptoPP::Integer pubX; CryptoPP::Integer pubY; pubX.Decode(x.getPtr(), x.getSize(), UNSIGNED); pubY.Decode(y.getPtr(), y.getSize(), UNSIGNED); BTC_ECPOINT publicPoint(pubX, pubY); // Initialize the public key with the ECP point just created cppPubKey.Initialize(CryptoPP::ASN1::secp256k1(), publicPoint); // Validate the public key -- not sure why this needs a PRNG BTC_PRNG prng; return cppPubKey.Validate(prng, 3); }
BTC_PRIVKEY CryptoECDSA::ParsePrivateKey(SecureBinaryData const & privKeyData) { BTC_PRIVKEY cppPrivKey; CryptoPP::Integer privateExp; privateExp.Decode(privKeyData.getPtr(), privKeyData.getSize(), UNSIGNED); cppPrivKey.Initialize(CryptoPP::ASN1::secp256k1(), privateExp); return cppPrivKey; }
template<> unsigned long Read(CryptoPP::Integer & val) { std::vector<unsigned char> data; unsigned long rValue = SimpleReader::Read(data); val.Decode(&data[0], data.size()); return rValue; }
BTC_PUBKEY CryptoECDSA::ParsePublicKey(SecureBinaryData const & pubKeyX32B, SecureBinaryData const & pubKeyY32B) { BTC_PUBKEY cppPubKey; CryptoPP::Integer pubX; CryptoPP::Integer pubY; pubX.Decode(pubKeyX32B.getPtr(), pubKeyX32B.getSize(), UNSIGNED); pubY.Decode(pubKeyY32B.getPtr(), pubKeyY32B.getSize(), UNSIGNED); BTC_ECPOINT publicPoint(pubX, pubY); // Initialize the public key with the ECP point just created cppPubKey.Initialize(CryptoPP::ASN1::secp256k1(), publicPoint); // Validate the public key -- not sure why this needs a PRNG BTC_PRNG prng; assert(cppPubKey.Validate(prng, 3)); return cppPubKey; }
///////////////////////////////////////////////////////////////////////////// // Deterministically generate new public key using a chaincode SecureBinaryData CryptoECDSA::ComputeChainedPublicKey( SecureBinaryData const & binPubKey, SecureBinaryData const & chainCode, SecureBinaryData* multiplierOut) { if(CRYPTO_DEBUG) { cout << "ComputeChainedPUBLICKey:" << endl; cout << " BinPub: " << binPubKey.toHexStr() << endl; cout << " BinChn: " << chainCode.toHexStr() << endl; } static SecureBinaryData SECP256K1_ORDER_BE = SecureBinaryData::CreateFromHex( "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141"); // Added extra entropy to chaincode by xor'ing with hash256 of pubkey BinaryData chainMod = binPubKey.getHash256(); BinaryData chainOrig = chainCode.getRawCopy(); BinaryData chainXor(32); for(uint8_t i=0; i<8; i++) { uint8_t offset = 4*i; *(uint32_t*)(chainXor.getPtr()+offset) = *(uint32_t*)( chainMod.getPtr()+offset) ^ *(uint32_t*)(chainOrig.getPtr()+offset); } // Parse the chaincode as a big-endian integer CryptoPP::Integer mult; mult.Decode(chainXor.getPtr(), chainXor.getSize(), UNSIGNED); // "new" init as "old", to make sure it's initialized on the correct curve BTC_PUBKEY oldPubKey = ParsePublicKey(binPubKey); BTC_PUBKEY newPubKey = ParsePublicKey(binPubKey); // Let Crypto++ do the EC math for us, serialize the new public key newPubKey.SetPublicElement( oldPubKey.ExponentiatePublicElement(mult) ); if(multiplierOut != NULL) (*multiplierOut) = SecureBinaryData(chainXor); //LOGINFO << "Computed new chained public key using:"; //LOGINFO << " Public key: " << binPubKey.toHexStr().c_str(); //LOGINFO << " PubKeyHash: " << chainMod.toHexStr().c_str(); //LOGINFO << " Chaincode: " << chainOrig.toHexStr().c_str(); //LOGINFO << " Multiplier: " << chainXor.toHexStr().c_str(); return CryptoECDSA::SerializePublicKey(newPubKey); }
bool CryptoECDSA::VerifyPublicKeyValid(SecureBinaryData const & pubKey) { if(CRYPTO_DEBUG) { cout << "BinPub: " << pubKey.toHexStr() << endl; } SecureBinaryData keyToCheck(65); // To support compressed keys, we'll just check to see if a key is compressed // and then decompress it. if(pubKey.getSize() == 33) { keyToCheck = UncompressPoint(pubKey); } else { keyToCheck = pubKey; } // Basically just copying the ParsePublicKey method, but without // the assert that would throw an error from C++ SecureBinaryData pubXbin(keyToCheck.getSliceRef( 1,32)); SecureBinaryData pubYbin(keyToCheck.getSliceRef(33,32)); CryptoPP::Integer pubX; CryptoPP::Integer pubY; pubX.Decode(pubXbin.getPtr(), pubXbin.getSize(), UNSIGNED); pubY.Decode(pubYbin.getPtr(), pubYbin.getSize(), UNSIGNED); BTC_ECPOINT publicPoint(pubX, pubY); // Initialize the public key with the ECP point just created BTC_PUBKEY cppPubKey; cppPubKey.Initialize(CryptoPP::ASN1::secp256k1(), publicPoint); // Validate the public key -- not sure why this needs a PRNG BTC_PRNG prng; return cppPubKey.Validate(prng, 3); }
void CBackProp::recalWeight(SOCKET conn) { // server // share the dwt // re apply AutoSeededRandomPool rnd; unsigned int bits = 512; DH dh; dh.AccessGroupParameters().GenerateRandomWithKeySize(rnd, bits); if(!dh.GetGroupParameters().ValidateGroup(rnd, 3)) throw runtime_error("Failed to validate prime and generator"); size_t count = 0; const Integer& p = dh.GetGroupParameters().GetModulus(); const Integer& q = dh.GetGroupParameters().GetSubgroupOrder(); Send(conn, p); Send(conn, q); CryptoPP::Integer g = RandomQuadraticResidue(p); Send(conn, g); CryptoPP::Integer ua = RandomQuadraticResidue(q); ModularArithmetic group_S(p); CryptoPP::Integer VA = group_S.Exponentiate(g, ua); // receive VB from Party B. byte output[128]; unsigned char buf[8]; CryptoPP::Integer VB; recv(conn,(char *)output, 128,0); VB.Decode(output, 128); CryptoPP::Integer rA1 = RandomQuadraticResidue(q); CryptoPP::Integer rA2 = RandomQuadraticResidue(q); for(int i=1;i<numl;i++) for(int j=0;j<lsize[i];j++) for(int k=0;k<lsize[i-1]+1;k++) { //Party A XA = dwt[i][j][k] YA = 10000.0 CryptoPP::Integer XA, YA; //dwt[i][j][k] = -1505; XA = (int)(dwt[i][j][k] / 2); YA = 1000 / 2; // divided by 10 //Send g and p, q to B CryptoPP::Integer xA1 = group_S.Exponentiate(g, rA1); CryptoPP::Integer xA2; if( XA >= 0) xA2 = (group_S.Exponentiate((VA * VB), rA1) * group_S.Exponentiate(g, XA)); else xA2 = group_S.Divide(group_S.Exponentiate((VA * VB), rA1) , group_S.Exponentiate(g, -XA)); CryptoPP::Integer yA1 = group_S.Exponentiate(g, rA2); CryptoPP::Integer yA2; if( YA >= 0) yA2 = (group_S.Exponentiate((VA * VB), rA2) * group_S.Exponentiate(g, YA)); else yA2 = group_S.Divide(group_S.Exponentiate((VA * VB), rA2), group_S.Exponentiate(g, -YA)); Send(conn, xA1); Send(conn, xA2); Send(conn, yA1); Send(conn, yA2); CryptoPP::Integer theta1, theta2, pi1, pi2; recv(conn,(char *)output, 128,0); theta1.Decode(output, 128); recv(conn,(char *)output, 128,0); theta2.Decode(output, 128); recv(conn,(char *)output, 128,0); pi1.Decode(output, 128); recv(conn,(char *)output, 128,0); pi2.Decode(output, 128); // compute eta CryptoPP::Integer eta1 = group_S.Divide(theta1 , group_S.Exponentiate(pi1, ua)); CryptoPP::Integer eta2 = group_S.Divide(theta2 , group_S.Exponentiate(pi2, ua)); Send(conn, eta1); Send(conn, eta2); //TODO: Receive the average result int peta1, peta2; recv(conn, (char *)buf, 4, 0); peta1 = (buf[0] << 24) + (buf[1] << 16) + (buf[2] << 8) + (buf[3] << 0); //cout << "peta1 " << peta1 << endl; recv(conn,(char *)buf, 4,0); peta2 = (buf[0] << 24) + (buf[1] << 16) + (buf[2] << 8) + (buf[3] << 0); //cout << "peta2 " << peta2 << endl; double avgWeight = (double)peta1 / ((double)peta2 * 10.0 ); weight[i][j][k] = prevWeight[i][j][k] + avgWeight; } }