MCPcopy Create free account
hub / github.com/ElementsProject/elements / SurjectOutput

Function SurjectOutput

src/blind.cpp:194–231  ·  view source on GitHub ↗

Create surjection proof

Source from the content-addressed store, hash-verified

192
193// Create surjection proof
194bool SurjectOutput(CTxOutWitness& txoutwit, const std::vector<secp256k1_fixed_asset_tag>& surjection_targets, const std::vector<secp256k1_generator>& target_asset_generators, const std::vector<uint256 >& target_asset_blinders, const std::vector<const unsigned char*> asset_blindptrs, const secp256k1_generator& output_asset_gen, const CAsset& asset)
195{
196 int ret;
197 // 1 to 3 targets
198 size_t nInputsToSelect = std::min(MAX_SURJECTION_TARGETS, surjection_targets.size());
199 unsigned char randseed[32];
200 GetStrongRandBytes(randseed, 32);
201 size_t input_index;
202 secp256k1_surjectionproof proof;
203 secp256k1_fixed_asset_tag tag;
204 memcpy(&tag, asset.begin(), 32);
205 // FIXME [hardfork] Elements currently cannot handle surjection proofs on transactions
206 // with more than 256 inputs. The Elements verification code will always try to give
207 // secp-zkp the complete list of inputs, and if this exceeds 256 then surjectionproof_verify
208 // will always return false, so there is no way to work around this situation at signing time
209 if (surjection_targets.size() > SECP256K1_SURJECTIONPROOF_MAX_N_INPUTS) {
210 // We must return false here to avoid triggering an assertion within
211 // secp256k1_surjectionproof_initialize on the next line.
212 return false;
213 }
214 // Find correlation between asset tag and listed input tags
215 if (secp256k1_surjectionproof_initialize(secp256k1_blind_context, &proof, &input_index, &surjection_targets[0], surjection_targets.size(), nInputsToSelect, &tag, 100, randseed) == 0) {
216 return false;
217 }
218 // Using the input chosen, build proof
219 ret = secp256k1_surjectionproof_generate(secp256k1_blind_context, &proof, target_asset_generators.data(), target_asset_generators.size(), &output_asset_gen, input_index, target_asset_blinders[input_index].begin(), asset_blindptrs[asset_blindptrs.size()-1]);
220 assert(ret == 1);
221 // Double-check answer
222 ret = secp256k1_surjectionproof_verify(secp256k1_blind_context, &proof, target_asset_generators.data(), target_asset_generators.size(), &output_asset_gen);
223 assert(ret != 0);
224
225 // Serialize into output witness structure
226 size_t output_len = secp256k1_surjectionproof_serialized_size(secp256k1_blind_context, &proof);
227 txoutwit.vchSurjectionproof.resize(output_len);
228 secp256k1_surjectionproof_serialize(secp256k1_blind_context, &txoutwit.vchSurjectionproof[0], &output_len, &proof);
229 assert(output_len == txoutwit.vchSurjectionproof.size());
230 return true;
231}
232
233// Creates ECDH nonce commitment using ephemeral key and output_pubkey
234uint256 GenerateOutputRangeproofNonce(CTxOut& out, const CPubKey output_pubkey)

Callers 1

BlindTransactionFunction · 0.85

Calls 10

GetStrongRandBytesFunction · 0.85
sizeMethod · 0.45
beginMethod · 0.45
dataMethod · 0.45
resizeMethod · 0.45

Tested by

no test coverage detected