Beispiel #1
0
        private static bool Secp256K1EcdsaSigSign(EcmultGenContext ctx, Scalar sigr, Scalar sigs, Scalar seckey, Scalar message, Scalar nonce, out byte recid)
        {
            var numArray = new byte[32];
            var r1       = new Ge();
            var scalar   = new Scalar();
            var overflow = false;
            GeJ r2;

            EcMultGen.secp256k1_ecmult_gen(ctx, out r2, nonce);
            Group.SetGeJ(r1, r2);
            Field.Normalize(r1.X);
            Field.Normalize(r1.Y);
            Field.GetB32(numArray, r1.X);
            Scalar.SetB32(sigr, numArray, ref overflow);
            recid = (byte)((overflow ? 2 : 0) | (Field.IsOdd(r1.Y) ? 1 : 0));
            Scalar.Mul(scalar, sigr, seckey);
            Scalar.Add(scalar, scalar, message);
            Scalar.Inverse(sigs, nonce);
            Scalar.Mul(sigs, sigs, scalar);
            Scalar.Clear(scalar);
            Group.secp256k1_gej_clear(r2);
            Group.secp256k1_ge_clear(r1);
            if (Scalar.IsZero(sigs))
            {
                return(false);
            }
            if (Scalar.IsHigh(sigs))
            {
                Scalar.Negate(sigs, sigs);
                recid ^= (byte)1;
            }
            return(true);
        }
        public static void secp256k1_ecmult_gen(EcmultGenContext ctx, out GeJ r, Scalar gn)
        {
            Ge        ge        = new Ge();
            GeStorage geStorage = new GeStorage();

            r = ctx.Initial.Clone();
            Scalar r1 = new Scalar();

            Scalar.Add(r1, gn, ctx.Blind);
            ge.Infinity = false;
            for (int index1 = 0; index1 < 64; ++index1)
            {
                uint bits = r1.GetBits(index1 * 4, 4);
                for (int index2 = 0; index2 < 16; ++index2)
                {
                    Group.StorageCmov(geStorage, ctx.Prec[index1][index2], (long)index2 == (long)bits);
                }
                Group.FromStorage(ge, geStorage);
                Group.GeJAddGe(r, r, ge);
            }
            Group.secp256k1_ge_clear(ge);
            Scalar.Clear(r1);
        }
            public uint256 BlindMessage(uint256 message, PubKey rpubkey, PubKey signerPubKey)
            {
                var         ctx = new ECMultGenContext();
                int         overflow;
                Span <byte> tmp = stackalloc byte[32];

                if (!Context.Instance.TryCreatePubKey(signerPubKey.ToBytes(), out var signerECPubkey))
                {
                    throw new FormatException("Invalid signer pubkey.");
                }
                if (!Context.Instance.TryCreatePubKey(rpubkey.ToBytes(), out var rECPubKey))
                {
                    throw new FormatException("Invalid r pubkey.");
                }
                var P = signerECPubkey.Q;
                var R = rECPubKey.Q.ToGroupElementJacobian();
                var t = FE.Zero;

retry:

                RandomUtils.GetBytes(tmp);
                _v = new Scalar(tmp, out overflow);
                if (overflow != 0 || _v.IsZero)
                {
                    goto retry;
                }
                RandomUtils.GetBytes(tmp);
                _w = new Scalar(tmp, out overflow);
                if (overflow != 0 || _v.IsZero)
                {
                    goto retry;
                }
                var A1 = ctx.MultGen(_v);
                var A2 = _w * P;
                var A  = R.AddVariable(A1, out _).AddVariable(A2, out _).ToGroupElement();

                t = A.x.Normalize();
                if (t.IsZero)
                {
                    goto retry;
                }
                using (var sha = new SHA256())
                {
                    message.ToBytes(tmp, false);
                    sha.Write(tmp);
                    t.WriteToSpan(tmp);
                    sha.Write(tmp);
                    sha.GetHash(tmp);
                }
                _c = new Scalar(tmp, out overflow);
                if (overflow != 0 || _c.IsZero)
                {
                    goto retry;
                }
                var cp = _c.Add(_w.Negate(), out overflow);                 // this is sent to the signer (blinded message)

                if (cp.IsZero || overflow != 0)
                {
                    goto retry;
                }
                cp.WriteToSpan(tmp);
                return(new uint256(tmp));
            }
Beispiel #4
0
        // [Fact(Skip = "Abs is unmanaged currently")] public void AbsBigInteger()
        //     => Assert.Equal(new BigInteger(5), Scalar.Abs(new BigInteger(-5)));


        [Fact] public void AddComplex()
        => Assert.Equal(new Complex(109, 5), Scalar.Add(new Complex(10, 5), 99));
Beispiel #5
0
 [Fact] public void AddBigInteger()
 => Assert.Equal(new BigInteger(100), Scalar.Add(BigInteger.One, 99));
Beispiel #6
0
        public void Process(MusigPubNonce combinedNonce)
        {
            if (processed_nonce)
            {
                throw new InvalidOperationException($"Nonce already processed");
            }
            var combined_pk = this.SigningPubKey;

            MusigSessionCache session_cache     = new MusigSessionCache();
            Span <byte>       noncehash         = stackalloc byte[32];
            Span <byte>       sig_template_data = stackalloc byte[32];

            Span <byte> combined_pk32 = stackalloc byte[32];
            Span <GEJ>  summed_nonces = stackalloc GEJ[2];

            summed_nonces[0] = combinedNonce.K1.Q.ToGroupElementJacobian();
            summed_nonces[1] = combinedNonce.K2.Q.ToGroupElementJacobian();

            combined_pk.WriteToSpan(combined_pk32);
            /* Add public adaptor to nonce */
            if (adaptor != null)
            {
                summed_nonces[0] = summed_nonces[0].AddVariable(adaptor.Q);
            }
            var combined_nonce = secp256k1_musig_process_nonces_internal(
                this.ctx.EcMultContext,
                noncehash,
                summed_nonces,
                combined_pk32,
                msg32);

            session_cache.B = new Scalar(noncehash);

            ECXOnlyPubKey.secp256k1_xonly_ge_serialize(sig_template_data, ref combined_nonce);
            var rx = combined_nonce.x;

            /* Negate nonce if Y coordinate is not square */
            combined_nonce = combined_nonce.NormalizeYVariable();
            /* Store nonce parity in session cache */
            session_cache.CombinedNonceParity = combined_nonce.y.IsOdd;

            /* Compute messagehash and store in session cache */
            ECXOnlyPubKey.secp256k1_musig_compute_messagehash(noncehash, sig_template_data, combined_pk32, msg32);
            session_cache.E = new Scalar(noncehash);

            /* If there is a tweak then set `msghash` times `tweak` to the `s`-part of the sig template.*/
            Scalar s = Scalar.Zero;

            if (is_tweaked)
            {
                Scalar e = session_cache.E;
                if (!ECPrivKey.secp256k1_eckey_privkey_tweak_mul(ref e, scalar_tweak))
                {
                    throw new InvalidOperationException("Impossible to sign (secp256k1_eckey_privkey_tweak_mul is false)");
                }
                if (pk_parity)
                {
                    e = e.Negate();
                }
                s = s.Add(e);
            }
            SessionCache       = session_cache;
            Template           = new SecpSchnorrSignature(rx, s);
            processed_nonce    = true;
            this.combinedNonce = combinedNonce;
        }