public static BigInt schoolMul(BigInt A, BigInt B) {
    assert(A.length() == B.length());
    int alen = A.length(), blen = B.length();
    int column = 0;
    BigInt product = new BigInt(); // answer
    for(int b = 0; b < blen; b++) { // for each digit in B
      BigInt row = new BigInt();
      Unsigned carry = new Unsigned(0);
      // Explicitly set zeros in columns
      for(int i = 0; i < b; i++) row.setDigit(i, BigInt.Zero_); 
      for(int a = 0; a < alen; a++) { // for each digit in A
        column = a + b;
        // multiple 
        DigitCarry dc1 = Arithmetic.mulDigits(B.getDigit(b), A.getDigit(a));
        // add carry to current value
        DigitCarry dc2 = Arithmetic.addDigits(dc1.digit(), carry, BigInt.Zero_);
        // set digit in this column
        row.setDigit(column, dc2.digit());
        // save carry
        carry.setValue(dc1.carry().value() + dc2.carry().value());
      }
      // add final carry 
      row.setDigit(column + 1, carry);
      // add to final product
      //product = StudentCode.add(product, row);
      BigInt sum = new BigInt();
      DigitCarry dcAdd = new DigitCarry();
      int len = product.length() > row.length() ? product.length() : row.length();
      for(int i = 0; i < len; i++) {
        dcAdd = Arithmetic.addDigits(product.getDigit(i), row.getDigit(i), dcAdd.carry());
        sum.setDigit(i, dcAdd.digit());
      }
      sum.setDigit(len, dcAdd.carry());
      product = sum;
    }
    return product;
  }