process static method

void process({
  1. required ByteData block,
  2. required Uint16List a,
  3. required Uint16List s,
  4. required Uint16List r,
  5. required Uint32List tmp,
  6. required int blockLength,
  7. required bool isLast,
})

Implementation

static void process({
  required ByteData block,
  required Uint16List a,
  required Uint16List s,
  required Uint16List r,
  required Uint32List tmp,
  required int blockLength,
  required bool isLast,
}) {
  //
  // Append 1
  //
  block.setUint8(blockLength, 1);
  for (var i = blockLength + 1; i < 17; i++) {
    block.setUint8(i, 0);
  }

  //
  // a += block
  //
  final t0 = block.getUint16(0, Endian.little);
  a[0] += 0x1FFF & t0;

  final t1 = block.getUint16(2, Endian.little);
  a[1] += 0x1FFF & ((t0 >> 13) | (t1 << 3));

  final t2 = block.getUint16(4, Endian.little);
  a[2] += 0x1FFF & ((t1 >> 10) | (t2 << 6));

  final t3 = block.getUint16(6, Endian.little);
  a[3] += 0x1FFF & ((t2 >> 7) | (t3 << 9));

  final t4 = block.getUint16(8, Endian.little);
  a[4] += 0x1FFF & ((t3 >> 4) | (t4 << 12));
  a[5] += 0x1FFF & (t4 >> 1);

  final t5 = block.getUint16(10, Endian.little);
  a[6] += 0x1FFF & ((t4 >> 14) | (t5 << 2));

  final t6 = block.getUint16(12, Endian.little);
  a[7] += 0x1FFF & ((t5 >> 11) | (t6 << 5));

  final t7 = block.getUint16(14, Endian.little);
  a[8] += 0x1FFF & ((t6 >> 8) | (t7 << 8));
  a[9] += (t7 >> 5) | (isLast ? 0 : (1 << 11));

  // In RFC:
  // a = (r * a) % p
  var carry = 0;
  for (var i = 0; i < 10; i++) {
    tmp[i] = carry;
    for (var j = 0; j < 10; j++) {
      final x = (j <= i) ? r[i - j] : (5 * r[10 + i - j]);
      tmp[i] += a[j] * x;
      if (j == 4) {
        carry = tmp[i] >> 13;
        tmp[i] = 0x1FFF & tmp[i];
      }
    }
    carry += tmp[i] >> 13;
    tmp[i] = 0x1FFF & tmp[i];
  }
  carry = (carry << 2) + carry;
  carry += tmp[0];
  tmp[0] = 0x1FFF & carry;
  carry = carry >> 13;
  tmp[1] += carry;
  for (var i = 0; i < 10; i++) {
    a[i] = 0xFFFF & tmp[i];
  }
}