emsaPSSVerify function
Implementation
bool emsaPSSVerify(List<int> mHash, List<int> em, int emBits, int sLen) {
// See RFC 8017, Section 9.1.2.
var hLen = 32;
var emLen = ((emBits + 7) / 8).floor();
if (emLen != em.length) {
return false;
}
// 1. If the length of M is greater than the input limitation for the
// hash function (2^61 - 1 octets for SHA-1), output "inconsistent"
// and stop.
//
// 2. Let mHash = Hash(M), an octet string of length hLen.
if (hLen != mHash.length) {
return false;
}
// 3. If emLen < hLen + sLen + 2, output "inconsistent" and stop.
if (emLen < hLen + sLen + 2) {
return false;
}
// 4. If the rightmost octet of EM does not have hexadecimal value
// 0xbc, output "inconsistent" and stop.
if (em.elementAt(emLen - 1) != 0xbc) {
return false;
}
// 5. Let maskedDB be the leftmost emLen - hLen - 1 octets of EM, and
// let H be the next hLen octets.
var db = em.sublist(0, emLen - hLen - 1);
var h = em.sublist(emLen - hLen - 1, emLen - 1);
// 6. If the leftmost 8 * emLen - emBits bits of the leftmost octet in
// maskedDB are not all equal to zero, output "inconsistent" and
// stop.
var bitMask = 0xff >> (8 * emLen - emBits);
if (em[0] & ~bitMask != 0) {
return false;
}
// 7. Let dbMask = MGF(H, emLen - hLen - 1).
//
// 8. Let DB = maskedDB \xor dbMask.
mgf1XOR(db, 0, db.length, h, 0, h.length);
// 9. Set the leftmost 8 * emLen - emBits bits of the leftmost octet in DB
// to zero.
db[0] &= bitMask;
// 10. If the emLen - hLen - sLen - 2 leftmost octets of DB are not zero
// or if the octet at position emLen - hLen - sLen - 1 (the leftmost
// position is "position 1") does not have hexadecimal value 0x01,
// output "inconsistent" and stop.
var psLen = emLen - hLen - sLen - 2;
for (int i = 0; i < psLen; i++) {
if (db[i] != 0x00) {
return false;
}
}
if (db[psLen] != 0x01) {
return false;
}
// 11. Let salt be the last sLen octets of DB.
var salt = db.sublist(db.length - sLen);
// 12. Let
// M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt ;
// M' is an octet string of length 8 + hLen + sLen with eight
// initial zero octets.
//
// 13. Let H' = Hash(M'), an octet string of length hLen.
List<int> tempList = [];
tempList.addAll([0, 0, 0, 0, 0, 0, 0, 0]);
tempList.addAll(mHash);
tempList.addAll(salt);
var digest = sha256.convert(tempList);
var digestBytes = digest.bytes;
// 14. If H = H', output "consistent." Otherwise, output "inconsistent."
for (int i = 0; i < digestBytes.length; i++) {
if (digestBytes[i] != h[i]) {
return false;
}
}
return true;
}