public static FourierPoint operator >>(FourierPoint x, int shift) { ulong[] number = new ulong[2] { x.Low, x.High }; while (shift >= 64) { ulong carry = AsmX64Operations.MultiplyDigitAndAdd(PrimeModuloDigits, NegativeInverseLowP * number[0], number, 2); number[0] = number[1]; number[1] = carry; shift -= 64; } if (shift != 0) { ulong mask = (1UL << shift) - 1UL; ulong carry = AsmX64Operations.MultiplyDigitAndAdd(PrimeModuloDigits, NegativeInverseLowP * number[0] & mask, number, 2); return(new FourierPoint((number[0] >> shift) | (number[1] << (64 - shift)), (number[1] >> shift) | (carry << (64 - shift)))); } return(new FourierPoint(number[0], number[1])); }
//return: P * factor on the elliptic curves domain. public OwnECPoint Multiply(OwnECPoint p, ulong[] factor) { ulong[] exp = new ulong[factor.Length + 1]; ulong[] exp3 = new ulong[factor.Length + 1]; factor.CopyTo(exp, 0); exp3[factor.Length] = AsmX64Operations.MultiplyDigitAndAdd(exp, 3, exp3, factor.Length); for (int i = exp.Length; --i >= 0;) { exp3[i] ^= exp[i]; //exp3= (exp*3) ^ exp } int high = HighBit(exp3); if (high < 0) { return(new OwnECPoint(p.X, p.Y, true)); } JacobianECPoint x = new JacobianECPoint(p.X, p.Y, true); ulong mask = 1UL << (high & 63); for (int i = high; --i >= 0;) { GetDouble(ref x); if ((exp3[(i + 1) >> 6] & mask) != 0) { if ((exp[(i + 1) >> 6] & mask) != 0) { Subtract(ref x, p); } else { Add(ref x, p); } } mask = (mask >> 1) | (mask << 63); } OwnECPoint result = x.ToECPoint(this); return(result); }