Compute the scalar offset used for the final blinder computation value * asset_blinder + value_blinder FIXME this method should be in libsecp, as should `ComputeAndAddToScalarOffset`
| 313 | // value * asset_blinder + value_blinder |
| 314 | // FIXME this method should be in libsecp, as should `ComputeAndAddToScalarOffset` |
| 315 | bool CalculateScalarOffset(uint256& out, CAmount value, const uint256& asset_blinder, const uint256& value_blinder) |
| 316 | { |
| 317 | // If the asset_blinder is 0, then the equation resolves to just the value_blinder |
| 318 | if (asset_blinder.IsNull()) { |
| 319 | out = value_blinder; |
| 320 | return true; |
| 321 | } |
| 322 | |
| 323 | out = asset_blinder; |
| 324 | uint256 val; |
| 325 | // tweak_mul expects a 32 byte, big endian tweak. |
| 326 | // We need to pack the 8 byte CAmount into a uint256 with the correct padding, so start it at 24 bytes from the front |
| 327 | WriteBE64(val.begin() + 24, value); |
| 328 | if (value > 0) { |
| 329 | if (secp256k1_ec_seckey_tweak_mul(secp256k1_blind_context, out.begin(), val.begin()) != 1) return false; |
| 330 | } else { |
| 331 | out = value_blinder; |
| 332 | return true; |
| 333 | } |
| 334 | if (!value_blinder.IsNull()) { |
| 335 | uint256 value_negated = value_blinder; |
| 336 | if (secp256k1_ec_seckey_negate(secp256k1_blind_context, value_negated.begin()) != 1) { |
| 337 | return false; |
| 338 | } |
| 339 | // Special-case zero, which would otherwise cause `secp256k1_ec_seckey_tweak_add` to fail |
| 340 | if (value_negated == out) { |
| 341 | out = uint256{}; |
| 342 | return true; |
| 343 | } |
| 344 | if (secp256k1_ec_seckey_tweak_add(secp256k1_blind_context, out.begin(), value_blinder.begin()) != 1) return false; |
| 345 | } |
| 346 | return true; |
| 347 | } |
| 348 | |
| 349 | // Computes a scalar offset and adds it to another existing one |
| 350 | bool ComputeAndAddToScalarOffset(uint256& a, CAmount value, const uint256& asset_blinder, const uint256& value_blinder) |
no test coverage detected