verify method

bool verify(
  1. RSAPublicKey key,
  2. dynamic signature,
  3. dynamic msg
)
override

Implementation

bool verify(
    RSAPublicKey key,
    /* String | List<int> | BigInt */ signature,
    /* String | List<int> | BigInt */ msg) {
  int emBits = key.bitSize - 1;

  List<int> msgBytes;
  if (msg is List<int>) {
    msgBytes = msg;
  } else if (msg is Iterable<int>) {
    msgBytes = msg.toList();
  } else if (msg is String) {
    msgBytes = utf8.encode(msg);
  } else if (msg is BigInt) {
    msgBytes = bigIntToBytes(msg);
  } else {
    throw Exception('Unknown type');
  }

  final mHash = hasher.convert(msgBytes).bytes;
  final hashLength = mHash.length;

  if (emBits < (8 * (hashLength + saltLength) + 9)) {
    throw Exception('emBits too small');
  }

  final em = key.engine.unsign(signature);

  if (em.length < hashLength + saltLength + 2) {
    throw Exception('inconsistent. encoded message length small');
  }

  if (em.last != 0xbc) {
    throw Exception('inconsistent. bc octet not found in encoded message');
  }

  final maskedDb = em.take(key.blockSize - hashLength - 1);
  final h = em.skip(key.blockSize - hashLength - 1).take(hashLength);

  final dbMask = mgf.encode(maskedDb.length, h);

  final db = ListOps.xor(maskedDb, dbMask);

  int emDiff = (8 * key.blockSize) - (emBits);
  if (emDiff < 0) {
    throw Exception();
  } else if (emDiff > 7) {
    throw Exception();
  }

  db[0] &= (1 << emDiff) - 1;

  final ps = db.take(key.blockSize - hashLength - saltLength - 2);
  if (ps.any((element) => element != 0)) {
    throw Exception('inconsistent. invalid ps');
  }
  if (db.skip(key.blockSize - hashLength - saltLength - 2).first != 0x01) {
    throw Exception('inconsistents');
  }

  final salt = db.skip(key.blockSize - hashLength - saltLength - 1);

  final mDash = <int>[
    ...List<int>.filled(8, 0),
    ...mHash,
    ...salt,
  ];

  final hDash = hasher.convert(mDash).bytes;

  return iterableEquality.equals(h, hDash);
}