public void dlc_schnorr_test() { var arr = JArray.Parse(File.ReadAllText("Data/dlc_schnorr_test.json")); foreach (var vector in arr.OfType <JObject>()) { var privKey = Context.Instance.CreateECPrivKey(Encoders.Hex.DecodeData(vector["inputs"]["privKey"].Value <string>())); var privNonce = Context.Instance.CreateECPrivKey(Encoders.Hex.DecodeData(vector["inputs"]["privNonce"].Value <string>())); var hash = Encoders.Hex.DecodeData(vector["inputs"]["msgHash"].Value <string>()); var pubkey = Context.Instance.CreateXOnlyPubKey(Encoders.Hex.DecodeData(vector["pubKey"].Value <string>())); var nonce = new SchnorrNonce(Context.Instance.CreateXOnlyPubKey(Encoders.Hex.DecodeData(vector["pubNonce"].Value <string>()))); Assert.Equal(nonce, privNonce.CreateSchnorrNonce()); Assert.Equal(pubkey, privKey.CreateXOnlyPubKey()); Assert.True(new OracleInfo(pubkey, nonce).TryComputeSigpoint(new DiscreteOutcome(hash), out var sigpoint)); Assert.True(Context.Instance.TryCreatePubKey(Encoders.Hex.DecodeData(vector["sigPoint"].Value <string>()), out var expectedSigPoint)); Assert.Equal(expectedSigPoint, sigpoint); Assert.True(SecpSchnorrSignature.TryCreate(Encoders.Hex.DecodeData(vector["signature"].Value <string>()), out var expectedSig)); Assert.Equal(expectedSig.rx, nonce.PubKey.Q.x); var expectedAttestation = expectedSig.s; var sig = privKey.SignBIP340(hash, new PrecomputedNonceFunctionHardened(privNonce.ToBytes())); Assert.Equal(expectedSig.rx, sig.rx); Assert.Equal(expectedSig.s, sig.s); } }
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); }
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)); }
protected override async Task InvokeAsyncBase(InvocationContext context) { EventFullName evt = context.GetEventName(); var rNonce = context.ParseResult.CommandResult.GetArgumentValueOrDefault <string>("nonce")?.ToLowerInvariant().Trim(); if (rNonce is null) { throw new CommandOptionRequiredException("nonce"); } if (!SchnorrNonce.TryParse(rNonce, out var nonce) || nonce is null) { throw new CommandException("nonce", "Invalid nonce"); } var oracle = await GetOracle("eventfullname", evt.OracleName); var outcomes = context.GetOutcomes(); var evtId = new OracleInfo(oracle.PubKey !, nonce); if (!await Repository.AddEvent(evtId, outcomes.ToArray())) { throw new CommandException("eventfullname", "The specified event already exists"); } await NameRepository.AsEventRepository().SetMapping(evtId, evt.Name); }
protected override async Task InvokeAsyncBase(InvocationContext context) { var eventName = context.ParseResult.CommandResult.GetArgumentValueOrDefault <string>("name")?.Trim(); if (eventName is null) { throw new CommandOptionRequiredException("name"); } if (!EventFullName.TryParse(eventName, out EventFullName? evt) || evt is null) { throw new CommandException("name", "Invalid event full name, should be in the form 'oracleName/eventName'"); } var rNonce = context.ParseResult.CommandResult.GetArgumentValueOrDefault <string>("nonce")?.ToLowerInvariant().Trim(); if (rNonce is null) { throw new CommandOptionRequiredException("nonce"); } if (!SchnorrNonce.TryParse(rNonce, out var nonce) || nonce is null) { throw new CommandException("nonce", "Invalid nonce"); } var outcomes = context.GetOutcomes(); if (!await Repository.OracleExists(evt.OracleName)) { throw new CommandException("name", "The specified oracle do not exists"); } if (!await Repository.AddEvent(evt, nonce, outcomes.ToArray())) { throw new CommandException("name", "The specified event already exists"); } }
public async Task <bool> AddEvent(EventFullName name, SchnorrNonce nonce, string[] outcomes, RootedKeyPath?nonceKeyPath = null) { var oracle = await GetOracle(name.OracleName); if (oracle is null) { throw new InvalidOperationException("The oracle does not exists"); } var events = await GetEvents(oracle); var evt = GetEvent(name, events); if (evt is Event) { return(false); } evt = new Event() { Name = name.Name, Nonce = nonce, Outcomes = outcomes, NonceKeyPath = nonceKeyPath }; events.Add(evt); await SaveEvents(oracle, events); return(true); }
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; }
private SchnorrNonce GetSchnorrNonce(string?nonce) { var optionName = "nonce"; if (nonce is null) { throw new CommandOptionRequiredException(optionName); } if (!SchnorrNonce.TryParse(nonce, out var n) || n is null) { throw new CommandException(optionName, "Invalid pubkey"); } return(n); }
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); }
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 <OracleInfo?> GetEventId(EventFullName eventFullName) { var oracleId = await NameRepository.AsOracleNameRepository().GetId(eventFullName.OracleName); if (oracleId is null) { return(null); } var id = await NameRepository.GetId(Scopes.Events, GetEventFullName(oracleId, eventFullName.Name)); if (id is null) { return(null); } if (!SchnorrNonce.TryParse(id, out var nonce)) { return(null); } return(new OracleInfo(oracleId.PubKey, nonce)); }
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); }
public Task <Event?> GetEvent(ECXOnlyPubKey oraclePubKey, SchnorrNonce nonce) { return(GetEvent(new OracleInfo(oraclePubKey, nonce))); }