public void SetSessionKey(String pubKeyString, String scrambler = null) { BigInteger pubKey = BigIntegerExtension.Create(pubKeyString, 16); if (scrambler == null) // Server SessionKey { // (Av^u) ^ b (mod N) SessionKey = pubKey.multiply(verifier.modPow(Scrambler, Modulus)).modPow(PrivateKey, Modulus); } else // Client SessionKey { Scrambler = BigIntegerExtension.Create(scrambler, 16); BigInteger temp = PrivateKey.add(Scrambler.multiply(SaltedIdentityHash)); SessionKey = pubKey.subtract((Generator.modPow(SaltedIdentityHash, Modulus)).multiply(Multiplier)).modPow(temp, Modulus); } }
// Client Constructor, username not needed, salt not generated by client public SRP6(byte[] identityHash, String modulus_N, int generator_g, String salt, string initialVector = "OFRna73m*aze01xY") { InitialVector = initialVector; Modulus = BigIntegerExtension.Create(modulus_N, 16); Generator = BigIntegerExtension.Create("" + generator_g, 10); Multiplier = BigIntegerExtension.Create("3", 10); Salt = BigIntegerExtension.Create(salt, 16); // Client-side variables PrivateKey = BigIntegerExtension.GeneratePseudoPrime(128, 100, new Random()); // g^a (mod N) PublicKey = this.generator_g.modPow(privateKey, this.modulus_N); // Server-side variables SaltedIdentityHash = bytesToBig(Sha1Hash(Salt.ToByteArray(), identityHash)); }
// Server Constructor, Radix 16 strings, 256-bit predef values public SRP6(byte[] identity, String modulus_N, int generator_g, int saltBits, int scramblerBits, string initialVector = "OFRna73m*aze01xY") { InitialVector = initialVector; Modulus = BigIntegerExtension.Create(modulus_N, 16); Generator = BigIntegerExtension.Create("" + generator_g, 10); Multiplier = BigIntegerExtension.Create("3", 10); Salt = BigIntegerExtension.Create(saltBits, new Random()); Scrambler = BigIntegerExtension.Create(scramblerBits, new Random()); // Server-side variables IdentityHash = identity; SaltedIdentityHash = bytesToBig(Sha1Hash(salt.ToByteArray(), identity)); Verifier = this.generator_g.modPow(saltedIdentityHash, this.modulus_N); // Random 128 bit number that is a probable prime PrivateKey = BigIntegerExtension.GeneratePseudoPrime(128, 100, new Random()); // kv + g^b (mod N) PublicKey = this.multiplier_k.multiply(verifier).add(this.generator_g.modPow(privateKey, this.modulus_N)); }
private static BigInteger bytesToBig(byte[] bytes) { return(BigIntegerExtension.Create(BytesToHex(bytes), 16)); }