/// Reduce a 64 byte / 512 bit scalar mod l public static UnpackedScalar from_bytes_wide(byte[] bytes) { var words = new ulong[8]; for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { words[i] |= ((ulong)bytes[(i * 8) + j]) << (j * 8); } } var mask = (((ulong)1) << 52) - 1; var lo = UnpackedScalar.zero(); var hi = UnpackedScalar.zero(); var los = lo.value.Span; var his = hi.value.Span; los[0] = words[0] & mask; los[1] = ((words[0] >> 52) | (words[1] << 12)) & mask; los[2] = ((words[1] >> 40) | (words[2] << 24)) & mask; los[3] = ((words[2] >> 28) | (words[3] << 36)) & mask; los[4] = ((words[3] >> 16) | (words[4] << 48)) & mask; his[0] = (words[4] >> 4) & mask; his[1] = ((words[4] >> 56) | (words[5] << 8)) & mask; his[2] = ((words[5] >> 44) | (words[6] << 20)) & mask; his[3] = ((words[6] >> 32) | (words[7] << 32)) & mask; his[4] = words[7] >> 20; lo = UnpackedScalar.montgomery_mul(lo, Constant.R); // (lo * R) / R = lo hi = UnpackedScalar.montgomery_mul(hi, Constant.RR); // (hi * R^2) / R = hi * R return(UnpackedScalar.add(hi, lo)); }
// Add public static Scalar operator +(Scalar lhs, Scalar rhs) { return(UnpackedScalar.add(lhs.unpack(), rhs.unpack()).pack()); }