extractPublicKey method
Implementation
Future<Uint8List> extractPublicKey(Uint8List message, Uint8List sig) async {
if ((sig.length != SignatureSize) || (sig[63] & 224 != 0)) {
throw ("bad signature format");
}
var h = Sha512().newHashSink();
h.add(sig.sublist(0, 32));
h.add(message);
h.close();
var hash = await h.hash();
Uint8List digest = Uint8List.fromList(hash.bytes);
Uint8List hReduced = Uint8List(32);
ScReduce(hReduced, digest);
Uint8List hInv = Uint8List(32);
hInv = InvertModL(hReduced);
Uint8List s = sig.sublist(32);
if (s.length != PublicKeySize) {
throw ("memory copy failed");
}
if (!ScMinimal(s)) throw ("invalid sig");
Uint8List one = new Uint8List(32);
one[0] = 1;
ExtendedGroupElement R = new ExtendedGroupElement();
Uint8List r = sig.sublist(0, 32);
if (!R.FromBytes(r))
throw ("failed to create extended group element from s");
FeNeg(R.X, R.X);
FeNeg(R.T, R.T);
ProjectiveGroupElement A = new ProjectiveGroupElement();
ExtendedGroupElement A2 = new ExtendedGroupElement();
GeDoubleScalarMultVartime(A, one, R, s);
A.ToExtended(A2);
ProjectiveGroupElement ecpk = new ProjectiveGroupElement();
GeScalarMultVartime(ecpk, hInv, A2);
Uint8List pubkey = new Uint8List(PublicKeySize);
ecpk.ToBytes(pubkey);
return pubkey;
}