Esempio n. 1
0
        public static bool TryExtractPrivateKey(this ECPubKey pubKey, ReadOnlySpan <byte> msg1, SecpSchnorrSignature sig1, ReadOnlySpan <byte> msg2, SecpSchnorrSignature sig2, out ECPrivKey?key)
        {
            key = null;
            if (msg1.Length != 32)
            {
                return(false);
            }
            if (msg2.Length != 32)
            {
                return(false);
            }
            if (msg1.SequenceCompareTo(msg2) == 0)
            {
                return(false);
            }

            Span <byte> sig64 = stackalloc byte[64];

            sig1.WriteToSpan(sig64);
            Span <byte> pk_buf = stackalloc byte[32];
            Span <byte> buf    = stackalloc byte[32];

            pubKey.Q.x.WriteToSpan(pk_buf);
            using var sha = new SHA256();
            sha.InitializeTagged(TAG_BIP0340Challenge);
            sha.Write(sig64.Slice(0, 32));
            sha.Write(pk_buf);
            sha.Write(msg1);
            sha.GetHash(buf);

            var n1 = new Scalar(buf, out _);

            sig2.WriteToSpan(sig64);
            sha.InitializeTagged(TAG_BIP0340Challenge);
            sha.Write(sig64.Slice(0, 32));
            sha.Write(pk_buf);
            sha.Write(msg2);
            sha.GetHash(buf);

            var n2 = new Scalar(buf, out _);

            var s  = sig2.s + sig1.s.Negate();
            var n  = (n2 + n1.Negate());
            var sk = s * n.Inverse();

            if (pubKey.Q.y.IsOdd)
            {
                sk = sk.Negate();
            }
            if (!pubKey.ctx.TryCreateECPrivKey(sk, out key))
            {
                return(false);
            }
            return(true);
        }
        public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
        {
            string clientId     = string.Empty;
            string clientSecret = string.Empty;
            Client client       = null;

            if (!context.TryGetBasicCredentials(out clientId, out clientSecret))
            {
                context.TryGetFormCredentials(out clientId, out clientSecret);
            }

            if (context.ClientId == null)
            {
                //Remove the comments from the below line context.SetError, and invalidate context
                //if you want to force sending clientId/secrects once obtain access tokens.
                context.Validated();
                //context.SetError("invalid_clientId", "ClientId should be sent.");
                return(Task.FromResult <object>(null));
            }

            using (AuthRepository _repo = new AuthRepository())
            {
                client = _repo.FindClient(context.ClientId);
            }

            if (client == null)
            {
                context.SetError("invalid_clientId", string.Format("Client '{0}' is not registered in the system.", context.ClientId));
                return(Task.FromResult <object>(null));
            }

            if (client.ApplicationType == ApplicationTypes.NativeConfidential)
            {
                if (string.IsNullOrWhiteSpace(clientSecret))
                {
                    context.SetError("invalid_clientId", "Client secret should be sent.");
                    return(Task.FromResult <object>(null));
                }
                else
                {
                    if (client.Secret != SHA256.GetHash(clientSecret))
                    {
                        context.SetError("invalid_clientId", "Client secret is invalid.");
                        return(Task.FromResult <object>(null));
                    }
                }
            }

            if (!client.Active)
            {
                context.SetError("invalid_clientId", "Client is inactive.");
                return(Task.FromResult <object>(null));
            }

            context.OwinContext.Set <string>("as:clientAllowedOrigin", client.AllowedOrigin);
            context.OwinContext.Set <string>("as:clientRefreshTokenLifeTime", client.RefreshTokenLifeTime.ToString());

            context.Validated();
            return(Task.FromResult <object>(null));
        }
Esempio n. 3
0
        private static List <Client> BuildClientsList()
        {
            List <Client> ClientsList = new List <Client>
            {
                new Client
                {
                    Id                   = "ngAuthApp",
                    Secret               = SHA256.GetHash("abc@123"),
                    Name                 = "AngularJS front-end Application",
                    ApplicationType      = ApplicationTypes.JavaScript,
                    Active               = true,
                    RefreshTokenLifeTime = 7200,
                    AllowedOrigin        = "http://ngauthenticationweb.azurewebsites.net"
                },
                new Client
                {
                    Id                   = "consoleApp",
                    Secret               = SHA256.GetHash("123@abc"),
                    Name                 = "Console Application",
                    ApplicationType      = ApplicationTypes.NativeConfidential,
                    Active               = true,
                    RefreshTokenLifeTime = 14400,
                    AllowedOrigin        = "*"
                }
            };

            return(ClientsList);
        }
        internal static void secp256k1_musig_compute_noncehash(Span <byte> noncehash, Span <GE> aggnonce, ReadOnlySpan <byte> agg_pk32, ReadOnlySpan <byte> msg)
        {
            Span <byte> buf = stackalloc byte[33];

            using SHA256 sha = new SHA256();
            sha.InitializeTagged("MuSig/noncecoef");
            int i;

            for (i = 0; i < 2; i++)
            {
                ECPubKey.secp256k1_eckey_pubkey_serialize(buf, ref aggnonce[i], out _, true);
                sha.Write(buf);
            }
            sha.Write(agg_pk32.Slice(0, 32));
            sha.Write(msg.Slice(0, 32));
            sha.GetHash(noncehash);
        }
Esempio n. 5
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);
        }
        public void Receive(AuthenticationTokenReceiveContext context)
        {
            var allowedOrigin = context.OwinContext.Get <string> ("as:clientAllowedOrigin");

            context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { allowedOrigin });

            var hashedTokenId = SHA256.GetHash(context.Token);

            using (var repo = new AuthRepository( ))
            {
                var refreshToken = repo.GetRefreshToken(hashedTokenId);

                if (refreshToken != null)
                {
                    //Get protectedTicket from refreshToken class
                    context.DeserializeTicket(refreshToken.ProtectedTicket);
                    var result = repo.RemoveRefreshToken(hashedTokenId);
                }
            }
        }
Esempio n. 7
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);
        }
        public async Task CreateAsync(AuthenticationTokenCreateContext context)
        {
            var clientid = context.Ticket.Properties.Dictionary ["as:client_id"];

            if (string.IsNullOrEmpty(clientid))
            {
                return;
            }

            var refreshTokenId = Guid.NewGuid( ).ToString("n");

            using (var repo = new AuthRepository( ))
            {
                var refreshTokenLifeTime = context.OwinContext.Get <string> ("as:clientRefreshTokenLifeTime");

                var token = new RefreshToken
                {
                    Id         = SHA256.GetHash(refreshTokenId),
                    ClientId   = clientid,
                    Subject    = context.Ticket.Identity.Name,
                    IssuedUtc  = DateTime.UtcNow,
                    ExpiresUtc = DateTime.UtcNow.AddMinutes(Convert.ToDouble(refreshTokenLifeTime))
                };

                context.Ticket.Properties.IssuedUtc  = token.IssuedUtc;
                context.Ticket.Properties.ExpiresUtc = token.ExpiresUtc;

                token.ProtectedTicket = context.SerializeTicket( );

                var result = repo.AddRefreshToken(token);

                if (result)
                {
                    context.SetToken(refreshTokenId);
                }
            }
        }
        public static bool VerifySignature(uint256 message, UnblindedSignature signature, PubKey signerPubKey)
        {
            if (!Context.Instance.TryCreatePubKey(signerPubKey.ToBytes(), out var signerECPubkey))
            {
                throw new FormatException("Invalid signer pubkey.");
            }

            var P = signerECPubkey.Q;

            var sG = (signature.S * EC.G).ToGroupElement();
            var cP = P * signature.C;
            var R  = cP + sG;
            var t  = R.ToGroupElement().x.Normalize();

            using var sha = new SHA256();
            Span <byte> tmp = stackalloc byte[32];

            message.ToBytes(tmp, false);
            sha.Write(tmp);
            t.WriteToSpan(tmp);
            sha.Write(tmp);
            sha.GetHash(tmp);
            return(new Scalar(tmp) == signature.C);
        }
            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));
            }
Esempio n. 11
0
        public static bool TrySignAdaptor(this ECPrivKey key, ReadOnlySpan <byte> msg32, ECPubKey adaptor, out SecpECDSAAdaptorSignature?adaptorSignature, out SecpECDSAAdaptorProof?proof)
        {
            if (key == null)
            {
                throw new ArgumentNullException(nameof(key));
            }
            if (adaptor == null)
            {
                throw new ArgumentNullException(nameof(adaptor));
            }
            if (msg32.Length < 32)
            {
                throw new ArgumentException(paramName: nameof(msg32), message: "msg32 should be at least 32 bytes");
            }
            var    adaptor_ge = adaptor.Q;
            var    seckey32   = key.sec;
            SHA256 sha        = new SHA256();

            sha.Write(msg32.Slice(0, 32));
            Span <byte> buf33 = stackalloc byte[33];

            Internals.secp256k1_dleq_serialize_point(buf33, adaptor_ge);
            sha.Write(buf33);
            sha.GetHash(buf33);
            Span <byte> nonce32 = stackalloc byte[32];

            nonce_function_dleq(buf33, key.sec, "ECDSAAdaptorNon", nonce32);
            var k = new Scalar(nonce32);

            if (k.IsZero)
            {
                adaptorSignature = default;
                proof            = default;
                return(false);
            }
            var rpj = key.ctx.EcMultGenContext.MultGen(k);
            /* 2. R = k*Y; */
            var rj = adaptor_ge.MultConst(k, 256);

            /* 4. [sic] proof = DLEQ_prove((G,R'),(Y, R)) */
            if (!key.ctx.EcMultGenContext.secp256k1_dleq_proof("ECDSAAdaptorSig", k, adaptor_ge, out var dleq_proof_s, out var dleq_proof_e))
            {
                adaptorSignature = default;
                proof            = default;
                return(false);
            }

            /* 5. s' = k⁻¹(H(m) + x_coord(R)x) */
            var r   = rj.ToGroupElement();
            var msg = new Scalar(msg32);

            if (!secp256k1_ecdsa_adaptor_sign_helper(msg, k, r, key.sec, out var sp))
            {
                k = default;
                adaptorSignature = default;
                proof            = default;
                return(false);
            }

            /* 6. return (R, R', s', proof) */
            var rp = rpj.ToGroupElement();

            proof            = new SecpECDSAAdaptorProof(rp, dleq_proof_s, dleq_proof_e);
            adaptorSignature = new SecpECDSAAdaptorSignature(r, sp);
            k = default;
            return(true);
        }
Esempio n. 12
0
        internal static void secp256k1_nonce_function_musig(Span <Scalar> k, ReadOnlySpan <byte> session_id, ReadOnlySpan <byte> msg32, ReadOnlySpan <byte> key32, ReadOnlySpan <byte> agg_pk, ReadOnlySpan <byte> extra_input32)
        {
            using SHA256 sha = new SHA256();
            Span <byte> seed = stackalloc byte[32];
            Span <byte> i    = stackalloc byte[1];

            /* TODO: this doesn't have the same sidechannel resistance as the BIP340
             * nonce function because the seckey feeds directly into SHA. */
            sha.InitializeTagged("MuSig/nonce");
            sha.Write(session_id.Slice(0, 32));
            Span <byte> marker = stackalloc byte[1];

            if (msg32.Length is 32)
            {
                marker[0] = 32;
                sha.Write(marker);
                sha.Write(msg32);
            }
            else
            {
                marker[0] = 0;
                sha.Write(marker);
            }
            if (key32.Length is 32)
            {
                marker[0] = 32;
                sha.Write(marker);
                sha.Write(key32);
            }
            else
            {
                marker[0] = 0;
                sha.Write(marker);
            }

            if (agg_pk.Length is 32)
            {
                marker[0] = 32;
                sha.Write(marker);
                sha.Write(agg_pk);
            }
            else
            {
                marker[0] = 0;
                sha.Write(marker);
            }

            if (extra_input32.Length is 32)
            {
                marker[0] = 32;
                sha.Write(marker);
                sha.Write(extra_input32);
            }
            else
            {
                marker[0] = 0;
                sha.Write(marker);
            }

            sha.GetHash(seed);

            Span <byte> buf = stackalloc byte[32];

            for (i[0] = 0; i[0] < 2; i[0]++)
            {
                sha.Initialize();
                sha.Write(seed);
                sha.Write(i);
                sha.GetHash(buf);
                k[i[0]] = new Scalar(buf);
            }
        }