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)); }
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); }
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); } } }
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)); }
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); }
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); } }