/// <summary> /// Calculates B. /// </summary> /// <param name="N"></param> /// <param name="g"></param> /// <param name="b"></param> /// <param name="v"></param> /// <returns></returns> public static NetBigInteger CalcB(NetBigInteger N, NetBigInteger g, NetBigInteger b, NetBigInteger v) { //B = k*v + g^b % N NetBigInteger k = Calck(N, g); return((k.Multiply(v).Add(g.ModPow(b, N))).Mod(N)); }
//public byte[] GenerateObfuscationCallback() //{ // var _loc5_ = 0; // var _loc6_ = ""; // var _loc1_ = ""; // var _loc2_ = 0; // while (_loc2_ < 128) // { // _loc5_ = (int)(MathF.random() * 256); // _loc6_ = Convert.ToString(_loc5_, 16); // if (_loc6_.Length == 1) // { // _loc6_ = "0" + _loc6_; // } // _loc1_ = _loc1_ + _loc6_; // _loc2_++; // } // this.privateKey = new NetBigInteger(_loc1_, 16); // var _loc3_ = ENC_BASE_GENERATOR.ModPow(privateKey, ENC_PRIME_MODULUS); // var loc3Bytes = _loc3_.ToByteArray(); // Console.WriteLine("Generated key, L:" + loc3Bytes.Length); // return loc3Bytes; //} public byte[] GenerateObfuscationCallback() { var finalizedString = ""; for (int i = 0; i < 128; i++) { var randomNum = Convert.ToInt32(MathF.random() * 256); var randomizedString = Convert.ToString(randomNum, 16); if (randomizedString.Length == 1) { randomizedString = "0" + randomizedString; } finalizedString = finalizedString + randomizedString; } Console.WriteLine(finalizedString); // Output 0: a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1 // Output 1: b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7 // Output 2: dededededededededededededededededededededededededededededededededededededededededededededededededededededededededededededededededede3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a privateKey = new NetBigInteger(finalizedString, 16); var generatedKey = ENC_BASE_GENERATOR.ModPow(privateKey, ENC_PRIME_MODULUS); var bytes = generatedKey.ToByteArray(); Console.WriteLine("Generated key, L:" + bytes.Length); return(bytes); }
/// <summary> /// Generates Salt and Verifier for username and password /// </summary> /// <param name="username"></param> /// <param name="password"></param> /// <param name="keysize"></param> /// <param name="salt"></param> /// <returns></returns> public static NetBigInteger PasswordVerifier(String username, String password, Int32 keysize, out Byte[] salt) { salt = NetSRP.GenerateSalt(); NetBigInteger g, N = NetSRP.GetNandG(keysize, out g); return(NetSRP.PasswordVerifier(username, password, salt, N, g)); }
/// <summary> /// Calculates server's S. /// </summary> /// <param name="N"></param> /// <param name="A"></param> /// <param name="v"></param> /// <param name="u"></param> /// <param name="b"></param> /// <returns></returns> public static NetBigInteger CalcSServer(NetBigInteger N, NetBigInteger A, NetBigInteger v, NetBigInteger u, NetBigInteger b) { // Host: S = (Av^u) ^ b (computes session key) NetBigInteger S = (A.Multiply(v.ModPow(u, N))).ModPow(b, N); return(S); }
/// <summary> /// Returns 32 byte array using SHA256 one-way hash of value S. /// RijndaelManaged, for example can use max key of 32 bytes directly, /// so this is convienent. If you need more or less entropy, add or subtract /// bytes as required. Naturally, both sides need to be able to generate the same /// key bytes. It is recommended to just use the 32 bytes as returned from this /// method. /// </summary> /// <param name="S"></param> /// <returns></returns> public static Byte[] CalcK(NetBigInteger S) { SHA256 sha256 = SHA256.Create(); Byte[] ba = sha256.ComputeHash(S.ToByteArray()); return(ba); }
/// <summary> /// Returns N and g as an out parameter based on given keySize. /// </summary> /// <param name="keySize"></param> /// <param name="g"></param> /// <returns></returns> public static NetBigInteger GetNandG(Int32 keySize, out NetBigInteger g) { switch (keySize) { case 1024: g = g1024Bit; return(N1024Bit); case 1536: g = g1536Bit; return(N1536Bit); case 2048: g = g2048Bit; return(N2048Bit); case 3072: g = g3072Bit; return(N3072Bit); case 4096: g = g4096Bit; return(N4096Bit); case 6144: g = g6144Bit; return(N6144Bit); case 8192: g = g8192Bit; return(N8192Bit); } throw new ArgumentOutOfRangeException("Invalid key size."); }
/// <summary> /// Calculates client's S. /// </summary> /// <param name="N"></param> /// <param name="g"></param> /// <param name="B"></param> /// <param name="k"></param> /// <param name="x"></param> /// <param name="a"></param> /// <param name="u"></param> /// <returns></returns> public static NetBigInteger CalcSClient(NetBigInteger N, NetBigInteger g, NetBigInteger B, NetBigInteger k, NetBigInteger x, NetBigInteger a, NetBigInteger u) { // <premaster secret> = (B - (k * g^x)) ^ (a + (u * x)) % N // (B + (N - ((k*g.ModExp(x,N))%N))) - Do it this way. Thanks Valery. NetBigInteger S = (B.Add(N.Subtract((k.Multiply(g.ModPow(x, N))).Mod(N)))).ModPow(a.Add(u.Multiply(x)), N); return(S); }
/// <summary> /// Gets data from message /// </summary> /// <param name="message">source</param> protected override void Gets(NetIncomingMessage message) { this.Username = message.ReadString(); Int32 bytes = message.ReadInt32(); this.OtherData = bytes > 0 ? message.ReadBytes(bytes) : new Byte[0]; this.A = new NetBigInteger(message.ReadBytes(message.ReadInt32())); }
/// <summary> /// Compute client public ephemeral value (A) /// </summary> public static byte[] ComputeClientEphemeral(byte[] clientPrivateEphemeral) // a { // A= g^a (mod N) NetBigInteger a = new NetBigInteger(NetUtility.ToHexString(clientPrivateEphemeral), 16); NetBigInteger retval = g.ModPow(a, N); return(retval.ToByteArrayUnsigned()); }
/// <summary> /// Calculates k. /// </summary> /// <param name="N"></param> /// <param name="g"></param> /// <returns></returns> public static NetBigInteger Calck(NetBigInteger N, NetBigInteger g) { // k = SHA1(N | PAD(g)) SRP-6a Byte[] gBytes = g.ToByteArray(); Byte[] NBytes = N.ToByteArray(); Byte[] both = NetUtility.JoinArrays(NBytes, gBytes); Byte[] hash = hashAlgo.ComputeHash(both); return(new NetBigInteger(hash)); }
/// <summary> /// Generates key from request /// </summary> /// <param name="A">Generated A from request</param> /// <param name="v">Verifier v</param> private void KeyFromRequest(NetBigInteger A, NetBigInteger v) { // Shared random scrambler Lidgren.Network.NetBigInteger u = NetSRP.Calcu(A, _cache.B); // Sessionkey _cache.S = NetSRP.CalcSServer(N, A, v, u, _cache.b); _cache.K = NetSRP.CalcK(_cache.S); }
/// <summary> /// Creates a verifier that the server can later use to authenticate users later on (v) /// </summary> public static byte[] ComputeServerVerifier(byte[] privateKey) { NetBigInteger x = new NetBigInteger(NetUtility.ToHexString(privateKey), 16); // Verifier (v) = g^x (mod N) var serverVerifier = g.ModPow(x, N); return(serverVerifier.ToByteArrayUnsigned()); }
/// <summary> /// Calculates u. /// </summary> /// <param name="A"></param> /// <param name="B"></param> /// <returns></returns> public static NetBigInteger Calcu(NetBigInteger A, NetBigInteger B) { // Both: u = SHA1(PAD(A) | PAD(B)) Byte[] aBytes = A.ToByteArray(); Byte[] bBytes = B.ToByteArray(); Byte[] both = NetUtility.JoinArrays(aBytes, bBytes); Byte[] hash = hashAlgo.ComputeHash(both); return(new NetBigInteger(hash)); }
/// <summary> /// Calculates x. /// </summary> /// <param name="salt"></param> /// <param name="userName"></param> /// <param name="password"></param> /// <returns></returns> public static NetBigInteger Calcx(Byte[] salt, String userName, String password) { // x = SHA(s + SHA(userName + ":" + password)) Byte[] saltBytes = salt; Byte[] innerBytes = Encoding.UTF8.GetBytes(userName + ":" + password); Byte[] bytes = NetUtility.JoinArrays(saltBytes, innerBytes); Byte[] hash = hashAlgo.ComputeHash(bytes); NetBigInteger x = new NetBigInteger(hash); return(x); }
/// <summary> /// M2 is Server's proof of K. /// </summary> /// <returns></returns> public static Byte[] CalcM2(NetBigInteger A, Byte[] M, Byte[] K) { // Host -> User: H(A, M, K) Byte[] ABytes = A.ToByteArray(); ArrayList al = new ArrayList(); al.Add(ABytes); al.Add(M); al.Add(K); Byte[] all = NetUtility.JoinArrays(al); return(hashAlgo.ComputeHash(all)); }
/// <summary> /// Compute server ephemeral value (B) /// </summary> public static byte[] ComputeServerEphemeral(byte[] serverPrivateEphemeral, byte[] verifier) // b { var b = new NetBigInteger(NetUtility.ToHexString(serverPrivateEphemeral), 16); var v = new NetBigInteger(NetUtility.ToHexString(verifier), 16); // B = kv + g^b (mod N) var bb = g.ModPow(b, N); var kv = v.Multiply(k); var B = (kv.Add(bb)).Mod(N); return(B.ToByteArrayUnsigned()); }
public static byte[] ComputeServerSessionValue(byte[] clientPublicEphemeral, byte[] verifier, byte[] udata, byte[] serverPrivateEphemeral) { // S = (Av^u) ^ b (mod N) var A = new NetBigInteger(NetUtility.ToHexString(clientPublicEphemeral), 16); var v = new NetBigInteger(NetUtility.ToHexString(verifier), 16); var u = new NetBigInteger(NetUtility.ToHexString(udata), 16); var b = new NetBigInteger(NetUtility.ToHexString(serverPrivateEphemeral), 16); NetBigInteger retval = v.ModPow(u, N).Multiply(A).Mod(N).ModPow(b, N).Mod(N); return(retval.ToByteArrayUnsigned()); }
public static byte[] ComputeClientSessionValue(byte[] serverPublicEphemeral, byte[] xdata, byte[] udata, byte[] clientPrivateEphemeral) { // (B - kg^x) ^ (a + ux) (mod N) var B = new NetBigInteger(NetUtility.ToHexString(serverPublicEphemeral), 16); var x = new NetBigInteger(NetUtility.ToHexString(xdata), 16); var u = new NetBigInteger(NetUtility.ToHexString(udata), 16); var a = new NetBigInteger(NetUtility.ToHexString(clientPrivateEphemeral), 16); var bx = g.ModPow(x, N); var btmp = B.Add(N.Multiply(k)).Subtract(bx.Multiply(k)).Mod(N); return(btmp.ModPow(x.Multiply(u).Add(a), N).ToByteArrayUnsigned()); }
/// <summary> /// Returns A. /// </summary> /// <param name="N"></param> /// <param name="g"></param> /// <param name="a"></param> /// <returns></returns> public static NetBigInteger CalcA(NetBigInteger N, NetBigInteger g, NetBigInteger a) { // A = g^a % N if (g == null) { throw new ArgumentNullException("g"); } if (N == null) { throw new ArgumentNullException("N"); } return(g.ModPow(a, N)); }
public static NetBigInteger Create(string value) { int res; PexAssume.IsTrue(int.TryParse(value, out res)); NetBigInteger netBigInteger = new NetBigInteger(value); return(netBigInteger); // TODO: Edit factory method of NetBigInteger // This method should be able to configure the object in all possible ways. // Add as many parameters as needed, // and assign their values to each field by using the API. }
/// <summary> /// This functions generates a database entry for the given username and password. It /// is key that this function can only be called from a safe environment and that the /// password is sent safely to this function. Think about SSL encryption or one time /// one way keys and so forth. Do your best! We actually generate these on the client /// so the password is NEVER sent over the network, and then sent it over an encrypted /// channel. /// </summary> /// <param name="username"></param> /// <param name="password"></param> /// <param name="keysize"></param> /// <returns></returns> public static PlayerDatabaseEntry Generate(String username, String password, Int32 keysize) { Byte[] salt; // Calculates the verifier with a random salt // And we make sure the username is no longer case sensitive NetBigInteger verifier = Handshake.PasswordVerifier(username.ToLower().Trim(), password, keysize, out salt); // Returns the new entry return(new PlayerDatabaseEntry() { Username = username, Salt = salt, Verifier = verifier.ToByteArray() }); }
/// <summary> /// Generates Session key from response /// </summary> /// <param name="response"></param> /// <response></response> private NetSRP.Verification KeyFromResponse(NetSRP.Response response) { if ((Handshake.State.AllowVerificating & this.HandshakeState) != this.HandshakeState) { return(_verification); // Double Request } // When we get the response, get their public key B if (response.B.Mod(N).IntValue == 0) { this.HandshakeState = Handshake.State.Failed; throw new NetSRP.HandShakeException("Response contains invalid data", new ArgumentException("B mod N is zero.")); } // Shared random scrambler NetBigInteger u = NetSRP.Calcu(_cache.A, response.B); if (u.IntValue == 0) { this.HandshakeState = Handshake.State.Failed; throw new NetSRP.HandShakeException("Response contains invalid data", new ArgumentException("u is zero.")); } // Private key x NetBigInteger x = NetSRP.Calcx(response.Salt, _request.Username, _cache.UserData); // Cache Response; _response = response; // Session key _cache.S = NetSRP.CalcSClient(N, g, response.B, k, x, _cache.a, u); _cache.K = NetSRP.CalcK(_cache.S); // Create the verification _verification = new NetSRP.Verification(NetSRP.CalcM(N, g, _request.Username, response.Salt, _cache.A, response.B, _cache.K)); // Set State this.HandshakeState = Handshake.State.Verificating; return(_verification); }
/// <summary> /// M is client's proof of K. /// </summary> /// <returns></returns> public static Byte[] CalcM(NetBigInteger N, NetBigInteger g, String userName, Byte[] salt, NetBigInteger A, NetBigInteger B, Byte[] K) { // User -> Host: M = H(H(N) xor H(g), H(I), s, A, B, K) Byte[] gBytes = g.ToByteArray(); Byte[] NBytes = N.ToByteArray(); Byte[] hg = hashAlgo.ComputeHash(gBytes); Byte[] hN = hashAlgo.ComputeHash(NBytes); Byte[] gNXorBytes = XorArrays(hN, hg); Byte[] userNameBytes = Encoding.UTF8.GetBytes(userName); Byte[] hUserNameBytes = hashAlgo.ComputeHash(userNameBytes); Byte[] ABytes = A.ToByteArray(); Byte[] BBytes = B.ToByteArray(); ArrayList al = new ArrayList(); al.Add(gNXorBytes); al.Add(hUserNameBytes); al.Add(salt); al.Add(ABytes); al.Add(BBytes); al.Add(K); Byte[] all = NetUtility.JoinArrays(al); return(hashAlgo.ComputeHash(all)); }
/// <summary> /// Creates a new Handshake /// </summary> /// <param name="active">Is active party</param> /// <param name="keySize">keysize</param> /// <param name="logonManager">logonManager (only needed if passive)</param> internal Handshake(Boolean active, Int32 keySize, ILogonManager logonManager) { // Local Data setup _cache = new NetSRP.State(); _keySize = keySize; _logonManager = logonManager ?? _defaultLogonManager; if (!active && _defaultLogonManager == null) { _defaultLogonManager = logonManager; } // We calculate N and G for this insance. I choose to do so, so you can // have different keysizes throughout your program and are not stuck with one N = NetSRP.GetNandG(_keySize, out g); k = NetSRP.Calck(N, g); // Set as NotInitialized this.HandshakeState = Handshake.State.NotInitialized; if (!active && _logonManager == null) { throw new InvalidOperationException("Receiving handshakes need a logonManager"); } if (keySize == 0 || N == null || g == null || k == null) { throw new InvalidOperationException("Handshake not intialized"); } // NOTE: this is caused by the length of the hailmessage - larger then 4096 goes over the MTU if (keySize < 1024 || keySize > 4096) { throw new NetException("SRP6Keysize is not supported by Lidgren.Network", new ArgumentOutOfRangeException("keySize")); } }
public NetBigInteger Mod( NetBigInteger m) { if (m.m_sign < 1) throw new ArithmeticException("Modulus must be positive"); NetBigInteger biggie = Remainder(m); return (biggie.m_sign >= 0 ? biggie : biggie.Add(m)); }
/// <summary> /// Compute server ephemeral value (B) /// </summary> public static byte[] ComputeServerEphemeral(byte[] serverPrivateEphemeral, byte[] verifier) // b { var b = new NetBigInteger(NetUtility.ToHexString(serverPrivateEphemeral), 16); var v = new NetBigInteger(NetUtility.ToHexString(verifier), 16); // B = kv + g^b (mod N) var bb = g.ModPow(b, N); var kv = v.Multiply(k); var B = (kv.Add(bb)).Mod(N); return B.ToByteArrayUnsigned(); }
public NetBigInteger[] DivideAndRemainder( NetBigInteger val) { if (val.m_sign == 0) throw new ArithmeticException("Division by zero error"); NetBigInteger[] biggies = new NetBigInteger[2]; if (m_sign == 0) { biggies[0] = Zero; biggies[1] = Zero; } else if (val.QuickPow2Check()) // val is power of two { int e = val.Abs().BitLength - 1; NetBigInteger quotient = Abs().ShiftRight(e); int[] remainder = LastNBits(e); biggies[0] = val.m_sign == m_sign ? quotient : quotient.Negate(); biggies[1] = new NetBigInteger(m_sign, remainder, true); } else { int[] remainder = (int[])m_magnitude.Clone(); int[] quotient = Divide(remainder, val.m_magnitude); biggies[0] = new NetBigInteger(m_sign * val.m_sign, quotient, true); biggies[1] = new NetBigInteger(m_sign, remainder, true); } return biggies; }
public NetBigInteger Max( NetBigInteger value) { return CompareTo(value) > 0 ? this : value; }
public NetBigInteger Add( NetBigInteger value) { if (m_sign == 0) return value; if (m_sign != value.m_sign) { if (value.m_sign == 0) return this; if (value.m_sign < 0) return Subtract(value.Negate()); return value.Subtract(Negate()); } return AddToMagnitude(value.m_magnitude); }
public int CompareTo( NetBigInteger value) { return m_sign < value.m_sign ? -1 : m_sign > value.m_sign ? 1 : m_sign == 0 ? 0 : m_sign * CompareNoLeadingZeroes(0, m_magnitude, 0, value.m_magnitude); }
/// <summary> /// Calculates V. The password verifier. /// </summary> /// <param name="N"></param> /// <param name="g"></param> /// <param name="x"></param> /// <returns></returns> public static NetBigInteger CalcV(NetBigInteger N, NetBigInteger g, NetBigInteger x) { // v = g^x % N return(g.ModPow(x, N)); }
/// <summary> /// Returns N and g as an out parameter based on given keySize. /// </summary> /// <param name="keySize"></param> /// <param name="g"></param> /// <returns></returns> public static NetBigInteger GetNandG(Int32 keySize, out NetBigInteger g) { switch (keySize) { case 1024: g = g1024Bit; return N1024Bit; case 1536: g = g1536Bit; return N1536Bit; case 2048: g = g2048Bit; return N2048Bit; case 3072: g = g3072Bit; return N3072Bit; case 4096: g = g4096Bit; return N4096Bit; case 6144: g = g6144Bit; return N6144Bit; case 8192: g = g8192Bit; return N8192Bit; } throw new ArgumentOutOfRangeException("Invalid key size."); }
/// <summary> /// Creates a new SRPRequest /// </summary> /// <param name="username">username</param> /// <param name="A">Public value</param> /// <param name="otherData">Other login data</param> public Request(String username, NetBigInteger A, Byte[] otherData) { this.Username = username; this.A = A; this.OtherData = otherData; }
/// <summary> /// Creates a verifier that the server can later use to authenticate users later on (v) /// </summary> public static byte[] ComputeServerVerifier(byte[] privateKey) { NetBigInteger x = new NetBigInteger(NetUtility.ToHexString(privateKey), 16); // Verifier (v) = g^x (mod N) var serverVerifier = g.ModPow(x, N); return serverVerifier.ToByteArrayUnsigned(); }
/// <summary> /// Creates a new SRPResponse /// </summary> /// <param name="salt">Salt</param> /// <param name="B">Public value</param> public Response(Byte[] salt, NetBigInteger B) { this.Salt = salt; this.B = B; }
/// <summary> /// Calculates x. /// </summary> /// <param name="salt"></param> /// <param name="userName"></param> /// <param name="password"></param> /// <returns></returns> public static NetBigInteger Calcx(Byte[] salt, String userName, String password) { // x = SHA(s + SHA(userName + ":" + password)) Byte[] saltBytes = salt; Byte[] innerBytes = Encoding.UTF8.GetBytes(userName + ":" + password); Byte[] bytes = NetUtility.JoinArrays(saltBytes, innerBytes); Byte[] hash = hashAlgo.ComputeHash(bytes); NetBigInteger x = new NetBigInteger(hash); return x; }
/// <summary> /// Gets data from message /// </summary> /// <param name="message">source</param> protected override void Gets(NetIncomingMessage message) { this.B = new NetBigInteger(message.ReadBytes(message.ReadInt32())); this.Salt = message.ReadBytes(message.ReadInt32()); }
/// <summary> /// Creates a new SRPRequest /// </summary> /// <param name="username">username</param> /// <param name="A">Public value</param> public Request(String username, NetBigInteger A) { this.Username = username; this.A = A; }
/// <summary> /// Computes the client session value /// </summary> public static byte[] ComputeClientSessionValue(byte[] serverPublicEphemeral, byte[] xdata, byte[] udata, byte[] clientPrivateEphemeral) { // (B - kg^x) ^ (a + ux) (mod N) var B = new NetBigInteger(NetUtility.ToHexString(serverPublicEphemeral), 16); var x = new NetBigInteger(NetUtility.ToHexString(xdata), 16); var u = new NetBigInteger(NetUtility.ToHexString(udata), 16); var a = new NetBigInteger(NetUtility.ToHexString(clientPrivateEphemeral), 16); var bx = g.ModPow(x, N); var btmp = B.Add(N.Multiply(k)).Subtract(bx.Multiply(k)).Mod(N); return btmp.ModPow(x.Multiply(u).Add(a), N).ToByteArrayUnsigned(); }
private static NetBigInteger createUValueOf( ulong value) { int msw = (int)(value >> 32); int lsw = (int)value; if (msw != 0) return new NetBigInteger(1, new int[] { msw, lsw }, false); if (lsw != 0) { NetBigInteger n = new NetBigInteger(1, new int[] { lsw }, false); // Check for a power of two if ((lsw & -lsw) == lsw) { n.m_numBits = 1; } return n; } return Zero; }
/// <summary> /// Computes the server session value /// </summary> public static byte[] ComputeServerSessionValue(byte[] clientPublicEphemeral, byte[] verifier, byte[] udata, byte[] serverPrivateEphemeral) { // S = (Av^u) ^ b (mod N) var A = new NetBigInteger(NetUtility.ToHexString(clientPublicEphemeral), 16); var v = new NetBigInteger(NetUtility.ToHexString(verifier), 16); var u = new NetBigInteger(NetUtility.ToHexString(udata), 16); var b = new NetBigInteger(NetUtility.ToHexString(serverPrivateEphemeral), 16); NetBigInteger retval = v.ModPow(u, N).Multiply(A).Mod(N).ModPow(b, N).Mod(N); return retval.ToByteArrayUnsigned(); }
public NetBigInteger And( NetBigInteger value) { if (m_sign == 0 || value.m_sign == 0) { return Zero; } int[] aMag = m_sign > 0 ? m_magnitude : Add(One).m_magnitude; int[] bMag = value.m_sign > 0 ? value.m_magnitude : value.Add(One).m_magnitude; bool resultNeg = m_sign < 0 && value.m_sign < 0; int resultLength = System.Math.Max(aMag.Length, bMag.Length); int[] resultMag = new int[resultLength]; int aStart = resultMag.Length - aMag.Length; int bStart = resultMag.Length - bMag.Length; for (int i = 0; i < resultMag.Length; ++i) { int aWord = i >= aStart ? aMag[i - aStart] : 0; int bWord = i >= bStart ? bMag[i - bStart] : 0; if (m_sign < 0) { aWord = ~aWord; } if (value.m_sign < 0) { bWord = ~bWord; } resultMag[i] = aWord & bWord; if (resultNeg) { resultMag[i] = ~resultMag[i]; } } NetBigInteger result = new NetBigInteger(1, resultMag, true); if (resultNeg) { result = result.Not(); } return result; }
private static NetBigInteger ExtEuclid( NetBigInteger a, NetBigInteger b, NetBigInteger u1Out, NetBigInteger u2Out) { NetBigInteger u1 = One; NetBigInteger u3 = a; NetBigInteger v1 = Zero; NetBigInteger v3 = b; while (v3.m_sign > 0) { NetBigInteger[] q = u3.DivideAndRemainder(v3); NetBigInteger tmp = v1.Multiply(q[0]); NetBigInteger tn = u1.Subtract(tmp); u1 = v1; v1 = tn; u3 = v3; v3 = q[1]; } if (u1Out != null) { u1Out.m_sign = u1.m_sign; u1Out.m_magnitude = u1.m_magnitude; } if (u2Out != null) { NetBigInteger tmp = u1.Multiply(a); tmp = u3.Subtract(tmp); NetBigInteger res = tmp.Divide(b); u2Out.m_sign = res.m_sign; u2Out.m_magnitude = res.m_magnitude; } return u3; }
public NetBigInteger Divide( NetBigInteger val) { if (val.m_sign == 0) throw new ArithmeticException("Division by zero error"); if (m_sign == 0) return Zero; if (val.QuickPow2Check()) // val is power of two { NetBigInteger result = Abs().ShiftRight(val.Abs().BitLength - 1); return val.m_sign == m_sign ? result : result.Negate(); } int[] mag = (int[])m_magnitude.Clone(); return new NetBigInteger(m_sign * val.m_sign, Divide(mag, val.m_magnitude), true); }
public NetBigInteger ModPow( NetBigInteger exponent, NetBigInteger m) { if (m.m_sign < 1) throw new ArithmeticException("Modulus must be positive"); if (m.Equals(One)) return Zero; if (exponent.m_sign == 0) return One; if (m_sign == 0) return Zero; int[] zVal = null; int[] yAccum = null; int[] yVal; // Montgomery exponentiation is only possible if the modulus is odd, // but AFAIK, this is always the case for crypto algo's bool useMonty = ((m.m_magnitude[m.m_magnitude.Length - 1] & 1) == 1); long mQ = 0; if (useMonty) { mQ = m.GetMQuote(); // tmp = this * R mod m NetBigInteger tmp = ShiftLeft(32 * m.m_magnitude.Length).Mod(m); zVal = tmp.m_magnitude; useMonty = (zVal.Length <= m.m_magnitude.Length); if (useMonty) { yAccum = new int[m.m_magnitude.Length + 1]; if (zVal.Length < m.m_magnitude.Length) { int[] longZ = new int[m.m_magnitude.Length]; zVal.CopyTo(longZ, longZ.Length - zVal.Length); zVal = longZ; } } } if (!useMonty) { if (m_magnitude.Length <= m.m_magnitude.Length) { //zAccum = new int[m.magnitude.Length * 2]; zVal = new int[m.m_magnitude.Length]; m_magnitude.CopyTo(zVal, zVal.Length - m_magnitude.Length); } else { // // in normal practice we'll never see .. // NetBigInteger tmp = Remainder(m); //zAccum = new int[m.magnitude.Length * 2]; zVal = new int[m.m_magnitude.Length]; tmp.m_magnitude.CopyTo(zVal, zVal.Length - tmp.m_magnitude.Length); } yAccum = new int[m.m_magnitude.Length * 2]; } yVal = new int[m.m_magnitude.Length]; // // from LSW to MSW // for (int i = 0; i < exponent.m_magnitude.Length; i++) { int v = exponent.m_magnitude[i]; int bits = 0; if (i == 0) { while (v > 0) { v <<= 1; bits++; } // // first time in initialise y // zVal.CopyTo(yVal, 0); v <<= 1; bits++; } while (v != 0) { if (useMonty) { // Montgomery square algo doesn't exist, and a normal // square followed by a Montgomery reduction proved to // be almost as heavy as a Montgomery mulitply. MultiplyMonty(yAccum, yVal, yVal, m.m_magnitude, mQ); } else { Square(yAccum, yVal); Remainder(yAccum, m.m_magnitude); Array.Copy(yAccum, yAccum.Length - yVal.Length, yVal, 0, yVal.Length); ZeroOut(yAccum); } bits++; if (v < 0) { if (useMonty) { MultiplyMonty(yAccum, yVal, zVal, m.m_magnitude, mQ); } else { Multiply(yAccum, yVal, zVal); Remainder(yAccum, m.m_magnitude); Array.Copy(yAccum, yAccum.Length - yVal.Length, yVal, 0, yVal.Length); ZeroOut(yAccum); } } v <<= 1; } while (bits < 32) { if (useMonty) { MultiplyMonty(yAccum, yVal, yVal, m.m_magnitude, mQ); } else { Square(yAccum, yVal); Remainder(yAccum, m.m_magnitude); Array.Copy(yAccum, yAccum.Length - yVal.Length, yVal, 0, yVal.Length); ZeroOut(yAccum); } bits++; } } if (useMonty) { // Return y * R^(-1) mod m by doing y * 1 * R^(-1) mod m ZeroOut(zVal); zVal[zVal.Length - 1] = 1; MultiplyMonty(yAccum, yVal, zVal, m.m_magnitude, mQ); } NetBigInteger result = new NetBigInteger(1, yVal, true); return exponent.m_sign > 0 ? result : result.ModInverse(m); }
public NetBigInteger Gcd( NetBigInteger value) { if (value.m_sign == 0) return Abs(); if (m_sign == 0) return value.Abs(); NetBigInteger r; NetBigInteger u = this; NetBigInteger v = value; while (v.m_sign != 0) { r = u.Mod(v); u = v; v = r; } return u; }
public NetBigInteger Modulus( NetBigInteger val) { return Mod(val); }
public NetBigInteger Min( NetBigInteger value) { return CompareTo(value) < 0 ? this : value; }
public NetBigInteger Multiply( NetBigInteger val) { if (m_sign == 0 || val.m_sign == 0) return Zero; if (val.QuickPow2Check()) // val is power of two { NetBigInteger result = ShiftLeft(val.Abs().BitLength - 1); return val.m_sign > 0 ? result : result.Negate(); } if (QuickPow2Check()) // this is power of two { NetBigInteger result = val.ShiftLeft(Abs().BitLength - 1); return m_sign > 0 ? result : result.Negate(); } int maxBitLength = BitLength + val.BitLength; int resLength = (maxBitLength + BitsPerInt - 1) / BitsPerInt; int[] res = new int[resLength]; if (val == this) { Square(res, m_magnitude); } else { Multiply(res, m_magnitude, val.m_magnitude); } return new NetBigInteger(m_sign * val.m_sign, res, true); }
public NetBigInteger ModInverse( NetBigInteger m) { if (m.m_sign < 1) throw new ArithmeticException("Modulus must be positive"); NetBigInteger x = new NetBigInteger(); NetBigInteger gcd = ExtEuclid(this, m, x, null); if (!gcd.Equals(One)) throw new ArithmeticException("Numbers not relatively prime."); if (x.m_sign < 0) { x.m_sign = 1; //x = m.Subtract(x); x.m_magnitude = doSubBigLil(m.m_magnitude, x.m_magnitude); } return x; }
public NetBigInteger Remainder( NetBigInteger n) { if (n.m_sign == 0) throw new ArithmeticException("Division by zero error"); if (m_sign == 0) return Zero; // For small values, use fast remainder method if (n.m_magnitude.Length == 1) { int val = n.m_magnitude[0]; if (val > 0) { if (val == 1) return Zero; int rem = Remainder(val); return rem == 0 ? Zero : new NetBigInteger(m_sign, new int[] { rem }, false); } } if (CompareNoLeadingZeroes(0, m_magnitude, 0, n.m_magnitude) < 0) return this; int[] result; if (n.QuickPow2Check()) // n is power of two { result = LastNBits(n.Abs().BitLength - 1); } else { result = (int[])m_magnitude.Clone(); result = Remainder(result, n.m_magnitude); } return new NetBigInteger(m_sign, result, true); }
/// <summary> /// Compute client public ephemeral value (A) /// </summary> public static byte[] ComputeClientEphemeral(byte[] clientPrivateEphemeral) // a { // A= g^a (mod N) NetBigInteger a = new NetBigInteger(NetUtility.ToHexString(clientPrivateEphemeral), 16); NetBigInteger retval = g.ModPow(a, N); return retval.ToByteArrayUnsigned(); }
public NetBigInteger ShiftLeft( int n) { if (m_sign == 0 || m_magnitude.Length == 0) return Zero; if (n == 0) return this; if (n < 0) return ShiftRight(-n); NetBigInteger result = new NetBigInteger(m_sign, ShiftLeft(m_magnitude, n), true); if (m_numBits != -1) { result.m_numBits = m_sign > 0 ? m_numBits : m_numBits + n; } if (m_numBitLength != -1) { result.m_numBitLength = m_numBitLength + n; } return result; }
public NetBigInteger Subtract( NetBigInteger n) { if (n.m_sign == 0) return this; if (m_sign == 0) return n.Negate(); if (m_sign != n.m_sign) return Add(n.Negate()); int compare = CompareNoLeadingZeroes(0, m_magnitude, 0, n.m_magnitude); if (compare == 0) return Zero; NetBigInteger bigun, lilun; if (compare < 0) { bigun = n; lilun = this; } else { bigun = this; lilun = n; } return new NetBigInteger(m_sign * compare, doSubBigLil(bigun.m_magnitude, lilun.m_magnitude), true); }
/// <summary> /// Host stores v (password verifier) in database. /// </summary> /// <param name="userName"></param> /// <param name="password"></param> /// <param name="salt"></param> /// <param name="N"></param> /// <param name="g"></param> /// <returns></returns> public static NetBigInteger PasswordVerifier(String userName, String password, Byte[] salt, NetBigInteger N, NetBigInteger g) { NetBigInteger x = NetSRP.Calcx(salt, userName, password); return NetSRP.CalcV(N, g, x); }
/// <summary> /// Host stores v (password verifier) in database. /// </summary> /// <param name="userName"></param> /// <param name="password"></param> /// <param name="salt"></param> /// <param name="N"></param> /// <param name="g"></param> /// <returns></returns> public static NetBigInteger PasswordVerifier(String userName, String password, Byte[] salt, NetBigInteger N, NetBigInteger g) { NetBigInteger x = NetSRP.Calcx(salt, userName, password); return(NetSRP.CalcV(N, g, x)); }