blob: 63877513c16541747ef325b809c2d85440536275 [file] [log] [blame]
library impl.srp_server;
import 'package:pointycastle/api.dart';
import 'package:pointycastle/srp/srp6_standard_groups.dart';
import 'package:pointycastle/srp/srp6_util.dart';
class SRP6Server implements SRPServer {
late BigInt N;
late BigInt g;
BigInt v;
SecureRandom random;
Digest digest;
BigInt? A;
BigInt? b;
BigInt? B;
BigInt? u;
BigInt? S;
BigInt? M1;
BigInt? M2;
BigInt? Key;
SRP6Server(
{required SRP6GroupParameters group,
required this.v,
required this.digest,
required this.random}) {
g = group.g;
N = group.N;
}
@override
BigInt? calculateSecret(BigInt clientA) {
A = SRP6Util.validatePublicValue(N, clientA);
u = SRP6Util.calculateU(digest, N, A, B);
S = _calculateS();
return S;
}
@override
BigInt? calculateServerEvidenceMessage() {
// Verify pre-requirements
if (A == null || M1 == null || S == null) {
throw Exception(
'Impossible to compute M2: some data are missing from the previous operations (A,M1,S)');
}
// Compute the server evidence message 'M2'
M2 = SRP6Util.calculateM2(digest, N, A!, M1!, S!);
return M2;
}
@override
BigInt? calculateSessionKey() {
// Verify pre-requirements
if (S == null || M1 == null || M2 == null) {
throw Exception(
'Impossible to compute Key: some data are missing from the previous operations (S,M1,M2)');
}
Key = SRP6Util.calculateKey(digest, N, S);
return Key;
}
@override
BigInt? generateServerCredentials() {
var k = SRP6Util.calculateK(digest, N, g);
b = selectPrivateValue();
B = (k * v + g.modPow(b!, N)) % N;
return B;
}
BigInt? selectPrivateValue() {
return SRP6Util.generatePrivateValue(digest, N, g, random);
}
@override
bool verifyClientEvidenceMessage(BigInt clientM1) {
// Verify pre-requirements
if (A == null || B == null || S == null) {
throw Exception(
'Impossible to compute and verify M1: some data are missing from the previous operations (A,B,S)');
}
// Compute the own client evidence message 'M1'
var computedM1 = SRP6Util.calculateM1(digest, N, A, B, S);
if (computedM1.compareTo(clientM1) == 0) {
M1 = clientM1;
return true;
}
return false;
}
BigInt _calculateS() {
return ((v.modPow(u!, N) * A!) % N).modPow(b!, N);
}
}