internal static void secp256k1_musig_nonce_process_internal( ECMultContext ecmult_ctx, out bool fin_nonce_parity, Span <byte> fin_nonce, out Scalar b, Span <GEJ> aggnoncej, ReadOnlySpan <byte> agg_pk32, ReadOnlySpan <byte> msg) { Span <byte> noncehash = stackalloc byte[32]; Span <GE> aggnonce = stackalloc GE[2]; aggnonce[0] = aggnoncej[0].ToGroupElement(); aggnonce[1] = aggnoncej[1].ToGroupElement(); secp256k1_musig_compute_noncehash(noncehash, aggnonce, agg_pk32, msg); /* aggnonce = aggnonces[0] + b*aggnonces[1] */ b = new Scalar(noncehash); var fin_nonce_ptj = ecmult_ctx.Mult(aggnoncej[1], b, null); fin_nonce_ptj = fin_nonce_ptj.Add(aggnonce[0]); var fin_nonce_pt = fin_nonce_ptj.ToGroupElement(); ECXOnlyPubKey.secp256k1_xonly_ge_serialize(fin_nonce, ref fin_nonce_pt); fin_nonce_pt = fin_nonce_pt.NormalizeYVariable(); fin_nonce_parity = fin_nonce_pt.y.IsOdd; }
private byte[] schnorrComputeSigPoint(byte[] data, byte[] nonce, byte[] pubKey, bool compressed) { Assert.True(ECXOnlyPubKey.TryCreate(pubKey, Context.Instance, out var pk)); Assert.True(SchnorrNonce.TryCreate(nonce, out var n)); Assert.True(new OracleInfo(pk, n).TryComputeSigpoint(new DiscreteOutcome(data), out var sigpoint)); return(sigpoint.ToBytes(compressed)); }
public Money Offer( ECXOnlyPubKey oraclePubKey, SchnorrNonce eventNonce, DiscretePayoffs offererPayoffs, Timeouts timeouts, Money?collateral = null) { using var tx = StartTransaction(); if (!s.IsInitiator) { throw new InvalidOperationException("The acceptor can't initiate an offer"); } s.OracleInfo = new OracleInfo(oraclePubKey, eventNonce); s.Timeouts = timeouts; s.OffererPayoffs = offererPayoffs; s.Offerer = new Party(); var minimumCollateral = offererPayoffs.CalculateMinimumCollateral(); if (collateral is Money m && m < minimumCollateral) { throw new ArgumentException($"The collateral is too small, it should be at least {minimumCollateral.ToString(false, false)}"); } s.Offerer.Collateral = collateral ?? minimumCollateral; tx.Commit(); return(s.Offerer.Collateral); }
public static string ToBase58(ECXOnlyPubKey pubKey) { var buf = new byte[32]; pubKey.WriteToSpan(buf); return(Encoders.Base58.EncodeData(buf)); }
private TaprootFullPubKey(ECXOnlyPubKey outputKey, bool outputParity, TaprootInternalPubKey internalKey, uint256?merkleRoot) : base(outputKey) { OutputKey = new TaprootPubKey(outputKey); OutputKeyParity = outputParity; InternalKey = internalKey; MerkleRoot = merkleRoot; }
public SchnorrNonce(ECXOnlyPubKey pubkey) { if (pubkey == null) { throw new ArgumentNullException(nameof(pubkey)); } PubKey = pubkey; }
public static bool TryCreate(ReadOnlySpan <byte> pubkey, [MaybeNullWhen(false)] out TaprootInternalPubKey result) { if (ECXOnlyPubKey.TryCreate(pubkey, out var k)) { result = new TaprootInternalPubKey(k); return(true); } result = null; return(false); }
public TaprootInternalPubKey(ReadOnlySpan <byte> pubkey) { if (pubkey.Length != 32) { throw new FormatException("The pubkey size should be 32 bytes"); } if (!ECXOnlyPubKey.TryCreate(pubkey, out var k)) { throw new FormatException("Invalid taproot pubkey"); } this.pubkey = k; }
public OracleInfo(ECXOnlyPubKey pubKey, SchnorrNonce rValue) { if (pubKey == null) { throw new ArgumentNullException(nameof(pubKey)); } if (rValue is null) { throw new ArgumentNullException(nameof(rValue)); } RValue = rValue; PubKey = pubKey; }
protected override async Task InvokeAsyncBase(InvocationContext context) { ECXOnlyPubKey oraclePubKey = GetOraclePubKey(context.ParseResult.ValueForOption <string>("oraclepubkey")); SchnorrNonce schnorrNonce = GetSchnorrNonce(context.ParseResult.ValueForOption <string>("nonce")); DLCTransactionBuilder builder = new DLCTransactionBuilder(true, null, null, null, Network); var timeouts = new Timeouts() { ContractMaturity = GetLockTime(context, "maturity") ?? new LockTime(0), ContractTimeout = GetLockTime(context, "expiration") ?? throw new CommandOptionRequiredException("expiration") }; var ci = GetOutcomes(context.ParseResult.ValueForOption <string[]>("outcome")); //var offer = builder.Offer(template, new OracleInfo(oraclePubKey, schnorrNonce), ci, timeouts); //WriteObject(context, offer); }
public void Process(MusigPubNonce aggregatedNonce) { if (processed_nonce) { throw new InvalidOperationException($"Nonce already processed"); } var agg_pk = this.SigningPubKey; MusigSessionCache session_cache = new MusigSessionCache(); Span <byte> fin_nonce = stackalloc byte[32]; Span <byte> agg_pk32 = stackalloc byte[32]; Span <GEJ> aggnonce_ptj = stackalloc GEJ[2]; aggnonce_ptj[0] = aggregatedNonce.K1.Q.ToGroupElementJacobian(); aggnonce_ptj[1] = aggregatedNonce.K2.Q.ToGroupElementJacobian(); agg_pk.WriteToSpan(agg_pk32); /* Add public adaptor to nonce */ if (adaptor != null) { aggnonce_ptj[0] = aggnonce_ptj[0].AddVariable(adaptor.Q); } secp256k1_musig_nonce_process_internal(this.ctx.EcMultContext, out session_cache.FinalNonceParity, fin_nonce, out session_cache.NonceCoeff, aggnonce_ptj, agg_pk32, msg32); /* Compute messagehash and store in session cache */ ECXOnlyPubKey.secp256k1_schnorrsig_challenge(out session_cache.Challenge, fin_nonce, msg32, agg_pk32); /* If there is a tweak then set `msghash` times `tweak` to the `s`-part of the sig template.*/ session_cache.SPart = Scalar.Zero; if (is_tweaked) { Scalar e_tmp = session_cache.Challenge; if (!ECPrivKey.secp256k1_eckey_privkey_tweak_mul(ref e_tmp, scalar_tweak)) { throw new InvalidOperationException("Impossible to sign (secp256k1_eckey_privkey_tweak_mul is false)"); } if (pk_parity) { e_tmp = e_tmp.Negate(); } session_cache.SPart = session_cache.SPart.Add(e_tmp); } fin_nonce.CopyTo(session_cache.FinalNonce); SessionCache = session_cache; processed_nonce = true; this.aggregateNonce = aggregatedNonce; }
internal TaprootAddress(string str, byte[] key, Network network) : base(str, network) { #if HAS_SPAN if (ECXOnlyPubKey.TryCreate(key, out var k)) { _PubKey = new TaprootPubKey(k); } else { throw new FormatException("Invalid TaprootAddress"); } #else _PubKey = new TaprootPubKey(key); #endif }
public async Task <Oracle?> TryGetOracle(string oracleName) { var id = await NameRepository.GetId(Scopes.Oracles, oracleName); if (id is null) { return(null); } ECXOnlyPubKey.TryCreate(Encoders.Hex.DecodeData(id), Context.Instance, out var pubkey); if (pubkey is null) { return(null); } return(await Repository.GetOracle(pubkey)); }
public async Task <bool> AddOracle(ECXOnlyPubKey pubKey, RootedKeyPath?rootedKeyPath = null) { var oracle = await GetOracle(pubKey); if (oracle is Oracle) { return(false); } oracle = new Oracle(); oracle.PubKey = pubKey; oracle.RootedKeyPath = rootedKeyPath; await SaveOracle(oracle); return(true); }
public async Task <Oracle?> GetOracle(ECXOnlyPubKey pubKey) { var dir = Path.Combine(RepositoryDirectory, "Oracles"); if (!Directory.Exists(dir)) { return(null); } var path = GetOracleFilePath(pubKey); if (!File.Exists(path)) { return(null); } return(JsonConvert.DeserializeObject <Oracle>(await File.ReadAllTextAsync(path), JsonSettings)); }
public TaprootInternalPubKey(byte[] pubkey) { if (pubkey.Length != 32) { throw new FormatException("The pubkey size should be 32 bytes"); } #if HAS_SPAN if (!ECXOnlyPubKey.TryCreate(pubkey, out var k)) { throw new FormatException("Invalid taproot pubkey"); } this.pubkey = k; #else pubkey.CopyTo(this.pubkey, 0); #endif }
public static bool TryParse(string str, [MaybeNullWhen(false)] out OracleId id) { id = null; if (!HexEncoder.IsWellFormed(str)) { return(false); } var bytes = Encoders.Hex.DecodeData(str); if (!ECXOnlyPubKey.TryCreate(bytes, Context.Instance, out var k) || k is null) { return(false); } id = new OracleId(k); return(true); }
internal static void secp256k1_musig_compute_noncehash(Span <byte> noncehash, Span <GE> summed_nonces, ReadOnlySpan <byte> combined_pk32, ReadOnlySpan <byte> msg) { Span <byte> buf = stackalloc byte[32]; using SHA256 sha = new SHA256(); sha.Initialize(); int i; for (i = 0; i < 2; i++) { ECXOnlyPubKey.secp256k1_xonly_ge_serialize(buf, ref summed_nonces[i]); sha.Write(buf); } sha.Write(combined_pk32.Slice(0, 32)); sha.Write(msg.Slice(0, 32)); sha.GetHash(noncehash); }
private static bool TryCreate(ReadOnlySpan <byte> input64, [MaybeNullWhen(false)] out OracleInfo oracleInfo) { oracleInfo = null; if (input64.Length != 64) { return(false); } if (!ECXOnlyPubKey.TryCreate(input64.Slice(0, 32), Context.Instance, out var pubkey) || pubkey is null) { return(false); } if (!SchnorrNonce.TryCreate(input64.Slice(32), out var rValue) || rValue is null) { return(false); } oracleInfo = new OracleInfo(pubkey, rValue); return(true); }
public async Task SetOracle(string oracleName, ECXOnlyPubKey pubKey, RootedKeyPath?rootedKeyPath = null) { var oracles = await GetOracles(); var oracle = GetOracle(oracleName, oracles); if (oracle is null) { oracle = new Oracle() { Name = oracleName }; oracles.Add(oracle); } oracle.PubKey = pubKey; oracle.RootedKeyPath = rootedKeyPath; await SaveOracles(oracles); }
internal MusigContext(ECXOnlyPubKey[] pubKeys, ReadOnlySpan <byte> msg32) { if (pubKeys == null) { throw new ArgumentNullException(nameof(pubKeys)); } if (pubKeys.Length is 0) { throw new ArgumentException(nameof(pubKeys), "There should be at least one pubkey in pubKeys"); } if (!(msg32.Length is 32)) { throw new ArgumentNullException(nameof(msg32), "msg32 should be 32 bytes."); } this.pubKeys = pubKeys; this.aggregatePubKey = ECXOnlyPubKey.MusigAggregate(pubKeys, this); this.ctx = pubKeys[0].ctx; this.msg32 = msg32.ToArray(); }
public MusigContext(MusigContext musigContext) { if (musigContext == null) { throw new ArgumentNullException(nameof(musigContext)); } musigContext.pk_hash.CopyTo(pk_hash.AsSpan()); second_pk_x = musigContext.second_pk_x; pk_parity = musigContext.pk_parity; is_tweaked = musigContext.is_tweaked; scalar_tweak = musigContext.scalar_tweak; internal_key_parity = musigContext.internal_key_parity; processed_nonce = musigContext.processed_nonce; SessionCache = musigContext.SessionCache?.Clone(); pubKeys = musigContext.pubKeys.ToArray(); aggregateNonce = musigContext.aggregateNonce; aggregatePubKey = musigContext.aggregatePubKey; tweakedPubKey = musigContext.tweakedPubKey; ctx = musigContext.ctx; msg32 = musigContext.msg32; }
protected override async Task InvokeAsyncBase(InvocationContext context) { var oracleName = context.ParseResult.CommandResult.GetArgumentValueOrDefault <string>("name")?.Trim(); if (oracleName is null) { throw new CommandOptionRequiredException("name"); } var pubkey = context.ParseResult.CommandResult.GetArgumentValueOrDefault <string>("pubkey")?.ToLowerInvariant()?.Trim(); if (pubkey is null) { throw new CommandOptionRequiredException("pubkey"); } var exists = await Repository.OracleExists(oracleName); if (exists && !Set) { throw new CommandException("name", "This oracle already exists"); } if (!exists && Set) { throw new CommandException("name", "This oracle does not exists"); } ECXOnlyPubKey?pubkeyObj; try { if (!ECXOnlyPubKey.TryCreate(Encoders.Hex.DecodeData(pubkey), Context.Instance, out pubkeyObj) || pubkeyObj is null) { throw new CommandException("pubkey", "Invalid pubkey"); } } catch (FormatException) { throw new CommandException("pubkey", "Invalid pubkey"); } await Repository.SetOracle(oracleName, pubkeyObj); }
public static new TaprootAddress Create(string bech32, Network expectedNetwork) { if (bech32 is null) { throw new ArgumentNullException(nameof(bech32)); } if (expectedNetwork is null) { throw new ArgumentNullException(nameof(expectedNetwork)); } bech32 = bech32.ToLowerInvariant(); if (expectedNetwork.GetBech32Encoder(Bech32Type.TAPROOT_ADDRESS, false) is Bech32Encoder encoder) { var decoded = encoder.Decode(bech32, out var v); #if HAS_SPAN if (v == 1 && ECXOnlyPubKey.TryCreate(decoded, out var k)) { return(new TaprootAddress(bech32, new TaprootPubKey(k), expectedNetwork)); } else { throw new FormatException("Invalid TaprootAddress"); } #else if (v == 1 && decoded.Length == 32) { return(new TaprootAddress(bech32, new TaprootPubKey(decoded), expectedNetwork)); } else { throw new FormatException("Invalid TaprootAddress"); } #endif } else { throw expectedNetwork.Bech32NotSupported(Bech32Type.TAPROOT_ADDRESS); } }
public static bool TryComputeSigPoint(this ECXOnlyPubKey pubkey, ReadOnlySpan <byte> msg32, SchnorrNonce rx, out ECPubKey?sigpoint) { if (rx == null) { throw new ArgumentNullException(nameof(rx)); } if (msg32.Length != 32) { throw new ArgumentException("Msg should be 32 bytes", nameof(msg32)); } sigpoint = null; Span <byte> buf = stackalloc byte[32]; Span <byte> pk_buf = stackalloc byte[32]; pubkey.WriteXToSpan(pk_buf); /* tagged hash(r.x, pk.x, msg32) */ using var sha = new SHA256(); sha.InitializeTagged(TAG_BIP0340Challenge); rx.fe.WriteToSpan(buf); sha.Write(buf); sha.Write(pk_buf); sha.Write(msg32); sha.GetHash(buf); if (!pubkey.TryMultTweak(buf, out var pubkey_ge) || pubkey_ge is null) { return(false); } if (!GE.TryCreateXQuad(rx.fe, out var rx_ge)) { return(false); } var pubkey_gej = pubkey_ge.Q.ToGroupElementJacobian(); var sigpoint_gej = pubkey_gej + rx_ge; var sigpoint_ge = sigpoint_gej.ToGroupElement(); sigpoint = new ECPubKey(sigpoint_ge, pubkey.ctx); return(true); }
private ECXOnlyPubKey GetOraclePubKey(string?pubkey) { var optionName = "oraclepubkey"; if (pubkey is null) { throw new CommandOptionRequiredException(optionName); } try { var hex = Encoders.Hex.DecodeData(pubkey); if (hex.Length != 32 || !ECXOnlyPubKey.TryCreate(hex, Context.Instance, out var r) || r is null) { throw new CommandException(optionName, "Invalid pubkey"); } return(r); } catch { throw new CommandException(optionName, "Invalid pubkey"); } }
public static bool TryParse(string str, out OracleInfo?oracleInfo) { oracleInfo = null; if (str == null) { throw new ArgumentNullException(nameof(str)); } var bytes = Encoders.Hex.DecodeData(str); if (bytes.Length != 64) { return(false); } if (!ECXOnlyPubKey.TryCreate(bytes.AsSpan().Slice(0, 32), Context.Instance, out var pubkey) || pubkey is null) { return(false); } if (!SchnorrNonce.TryCreate(bytes.AsSpan().Slice(32), out var rValue) || rValue is null) { return(false); } oracleInfo = new OracleInfo(pubkey, rValue); return(true); }
internal TaprootInternalPubKey(ECXOnlyPubKey pubkey) { this.pubkey = pubkey; }
public OracleId(ECXOnlyPubKey pubkey) { this.PubKey = pubkey; }
private bool schnorrVerify(byte[] sig, byte[] data, byte[] pubx) { Assert.True(NBitcoin.Secp256k1.SecpSchnorrSignature.TryCreate(sig, out var o)); Assert.True(ECXOnlyPubKey.TryCreate(pubx, Context.Instance, out var pub)); return(pub.SigVerifyBIP340(o, data)); }