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;
        }
示例#2
0
 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));
 }
示例#3
0
        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);
        }
示例#4
0
文件: Helpers.cs 项目: nicobst/NDLC
        public static string ToBase58(ECXOnlyPubKey pubKey)
        {
            var buf = new byte[32];

            pubKey.WriteToSpan(buf);
            return(Encoders.Base58.EncodeData(buf));
        }
示例#5
0
 private TaprootFullPubKey(ECXOnlyPubKey outputKey, bool outputParity, TaprootInternalPubKey internalKey, uint256?merkleRoot) : base(outputKey)
 {
     OutputKey       = new TaprootPubKey(outputKey);
     OutputKeyParity = outputParity;
     InternalKey     = internalKey;
     MerkleRoot      = merkleRoot;
 }
示例#6
0
 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;
 }
示例#9
0
 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;
 }
示例#10
0
 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;
        }
示例#12
0
        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
        }
示例#13
0
        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));
        }
示例#14
0
        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);
        }
示例#15
0
        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
        }
示例#17
0
文件: OracleId.cs 项目: dgarage/NDLC
        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);
        }
示例#18
0
        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);
        }
示例#19
0
 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);
 }
示例#20
0
        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;
 }
示例#23
0
        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);
        }
示例#24
0
        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);
            }
        }
示例#25
0
        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);
        }
示例#26
0
        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");
            }
        }
示例#27
0
        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;
 }
示例#29
0
文件: OracleId.cs 项目: dgarage/NDLC
 public OracleId(ECXOnlyPubKey pubkey)
 {
     this.PubKey = pubkey;
 }
示例#30
0
 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));
 }