public void montgomery_reduce_matches_from_bytes_mod_order_wide() { var bignum = new byte [64]; // set bignum = x + 2^256x for (int i = 0; i < 32; i++) { bignum[i] = X.Value[i]; bignum[32 + i] = X.Value[i]; } // x + 2^256x (mod l) // = 3958878930004874126169954872055634648693766179881526445624823978500314864344 var expected = new Scalar(new byte[] { 216, 154, 179, 139, 210, 121, 2, 71, 69, 99, 158, 216, 23, 173, 63, 100, 204, 0, 91, 50, 219, 153, 57, 249, 28, 82, 31, 197, 100, 165, 192, 8 }); var reduced = Scalar.from_bytes_mod_order_wide(bignum); // The reduced scalar should match the expected Assert.Equal(reduced.Value.ToArray(), expected.Value.ToArray()); // (x + 2^256x) * R var interim = UnpackedScalar.mul_internal(UnpackedScalar.from_bytes_wide(bignum).Value, Constant.R.Value); // ((x + 2^256x) * R) / R (mod l) var montgomery_reduced = UnpackedScalar.montgomery_reduce(interim); // The Montgomery reduced scalar should match the reduced one, as well as the expected Assert.Equal(montgomery_reduced.to_bytes(), reduced.unpack().to_bytes()); Assert.Equal(montgomery_reduced.to_bytes(), expected.unpack().to_bytes()); }