public override ECFieldElement Divide(ECFieldElement b) { uint[] z = Nat224.Create(); Mod.Invert(SecP224K1Field.P, ((SecP224K1FieldElement)b).x, z); SecP224K1Field.Multiply(z, this.x, z); return(new SecP224K1FieldElement(z)); }
public override ECFieldElement Invert() { //return new SecP224K1FieldElement(ToBigInteger().ModInverse(Q)); uint[] z = Nat224.Create(); Mod.Invert(SecP224K1Field.P, x, z); return(new SecP224K1FieldElement(z)); }
public override ECFieldElement Divide(ECFieldElement b) { //return Multiply(b.Invert()); uint[] z = Nat224.Create(); SecP224K1Field.Inv(((SecP224K1FieldElement)b).x, z); SecP224K1Field.Multiply(z, x, z); return(new SecP224K1FieldElement(z)); }
public override ECPoint Twice() { if (base.IsInfinity) { return(this); } ECCurve curve = this.Curve; SecP224R1FieldElement rawYCoord = (SecP224R1FieldElement)base.RawYCoord; if (rawYCoord.IsZero) { return(curve.Infinity); } SecP224R1FieldElement rawXCoord = (SecP224R1FieldElement)base.RawXCoord; SecP224R1FieldElement element3 = (SecP224R1FieldElement)base.RawZCoords[0]; uint[] z = Nat224.Create(); uint[] numArray2 = Nat224.Create(); uint[] numArray3 = Nat224.Create(); SecP224R1Field.Square(rawYCoord.x, numArray3); uint[] numArray4 = Nat224.Create(); SecP224R1Field.Square(numArray3, numArray4); bool isOne = element3.IsOne; uint[] x = element3.x; if (!isOne) { x = numArray2; SecP224R1Field.Square(element3.x, x); } SecP224R1Field.Subtract(rawXCoord.x, x, z); uint[] numArray6 = numArray2; SecP224R1Field.Add(rawXCoord.x, x, numArray6); SecP224R1Field.Multiply(numArray6, z, numArray6); SecP224R1Field.Reduce32(Nat224.AddBothTo(numArray6, numArray6, numArray6), numArray6); uint[] numArray7 = numArray3; SecP224R1Field.Multiply(numArray3, rawXCoord.x, numArray7); SecP224R1Field.Reduce32(Nat.ShiftUpBits(7, numArray7, 2, 0), numArray7); SecP224R1Field.Reduce32(Nat.ShiftUpBits(7, numArray4, 3, 0, z), z); SecP224R1FieldElement element4 = new SecP224R1FieldElement(numArray4); SecP224R1Field.Square(numArray6, element4.x); SecP224R1Field.Subtract(element4.x, numArray7, element4.x); SecP224R1Field.Subtract(element4.x, numArray7, element4.x); SecP224R1FieldElement y = new SecP224R1FieldElement(numArray7); SecP224R1Field.Subtract(numArray7, element4.x, y.x); SecP224R1Field.Multiply(y.x, numArray6, y.x); SecP224R1Field.Subtract(y.x, z, y.x); SecP224R1FieldElement element6 = new SecP224R1FieldElement(numArray6); SecP224R1Field.Twice(rawYCoord.x, element6.x); if (!isOne) { SecP224R1Field.Multiply(element6.x, element3.x, element6.x); } return(new SecP224R1Point(curve, element4, y, new ECFieldElement[] { element6 }, base.IsCompressed)); }
public override ECPoint Twice() { if (base.IsInfinity) { return(this); } ECCurve curve = Curve; SecP224K1FieldElement secP224K1FieldElement = (SecP224K1FieldElement)base.RawYCoord; if (secP224K1FieldElement.IsZero) { return(curve.Infinity); } SecP224K1FieldElement secP224K1FieldElement2 = (SecP224K1FieldElement)base.RawXCoord; SecP224K1FieldElement secP224K1FieldElement3 = (SecP224K1FieldElement)base.RawZCoords[0]; uint[] array = Nat224.Create(); SecP224K1Field.Square(secP224K1FieldElement.x, array); uint[] array2 = Nat224.Create(); SecP224K1Field.Square(array, array2); uint[] array3 = Nat224.Create(); SecP224K1Field.Square(secP224K1FieldElement2.x, array3); uint x = Nat224.AddBothTo(array3, array3, array3); SecP224K1Field.Reduce32(x, array3); uint[] array4 = array; SecP224K1Field.Multiply(array, secP224K1FieldElement2.x, array4); x = Nat.ShiftUpBits(7, array4, 2, 0u); SecP224K1Field.Reduce32(x, array4); uint[] array5 = Nat224.Create(); x = Nat.ShiftUpBits(7, array2, 3, 0u, array5); SecP224K1Field.Reduce32(x, array5); SecP224K1FieldElement secP224K1FieldElement4 = new SecP224K1FieldElement(array2); SecP224K1Field.Square(array3, secP224K1FieldElement4.x); SecP224K1Field.Subtract(secP224K1FieldElement4.x, array4, secP224K1FieldElement4.x); SecP224K1Field.Subtract(secP224K1FieldElement4.x, array4, secP224K1FieldElement4.x); SecP224K1FieldElement secP224K1FieldElement5 = new SecP224K1FieldElement(array4); SecP224K1Field.Subtract(array4, secP224K1FieldElement4.x, secP224K1FieldElement5.x); SecP224K1Field.Multiply(secP224K1FieldElement5.x, array3, secP224K1FieldElement5.x); SecP224K1Field.Subtract(secP224K1FieldElement5.x, array5, secP224K1FieldElement5.x); SecP224K1FieldElement secP224K1FieldElement6 = new SecP224K1FieldElement(array3); SecP224K1Field.Twice(secP224K1FieldElement.x, secP224K1FieldElement6.x); if (!secP224K1FieldElement3.IsOne) { SecP224K1Field.Multiply(secP224K1FieldElement6.x, secP224K1FieldElement3.x, secP224K1FieldElement6.x); } return(new SecP224K1Point(curve, secP224K1FieldElement4, secP224K1FieldElement5, new ECFieldElement[1] { secP224K1FieldElement6 }, base.IsCompressed)); }
private static void RS(uint[] d, uint[] e, uint[] f) { SecP224R1Field.Multiply(e, d, e); uint[] t = Nat224.Create(); SecP224R1Field.Square(d, t); SecP224R1Field.Add(f, t, d); SecP224R1Field.Twice(e, e); SecP224R1Field.Multiply(f, t, f); uint c = Nat.ShiftUpBits(7, f, 2, 0); SecP224R1Field.Reduce32(c, f); }
public static void Inv(uint[] x, uint[] z) { /* * Raise this element to the exponent 2^224 - 2^96 - 1 * * Breaking up the exponent's binary representation into "repunits", we get: * { 127 1s } { 1 0s } { 96 1s } * * Therefore we need an addition chain containing 96, 127 (the lengths of the repunits) * We use: 1, 2, 3, 6, 12, 24, 48, [96], 120, 126, [127] */ if (0 != IsZero(x)) { throw new ArgumentException("cannot be 0", "x"); } uint[] x1 = x; uint[] x2 = Nat224.Create(); Square(x1, x2); Multiply(x2, x1, x2); uint[] x3 = x2; Square(x2, x3); Multiply(x3, x1, x3); uint[] x6 = Nat224.Create(); SquareN(x3, 3, x6); Multiply(x6, x3, x6); uint[] x12 = x3; SquareN(x6, 6, x12); Multiply(x12, x6, x12); uint[] x24 = Nat224.Create(); SquareN(x12, 12, x24); Multiply(x24, x12, x24); uint[] x48 = x12; SquareN(x24, 24, x48); Multiply(x48, x24, x48); uint[] x96 = Nat224.Create(); SquareN(x48, 48, x96); Multiply(x96, x48, x96); uint[] x120 = x48; SquareN(x96, 24, x120); Multiply(x120, x24, x120); uint[] x126 = x24; SquareN(x120, 6, x126); Multiply(x126, x6, x126); uint[] x127 = x6; Square(x126, x127); Multiply(x127, x1, x127); uint[] t = x127; SquareN(t, 97, t); Multiply(t, x96, z); }
public override ECPoint LookupVar(int index) { uint[] x = Nat224.Create(), y = Nat224.Create(); int pos = index * SECP224R1_FE_INTS * 2; for (int j = 0; j < SECP224R1_FE_INTS; ++j) { x[j] = m_table[pos + j]; y[j] = m_table[pos + SECP224R1_FE_INTS + j]; } return(CreatePoint(x, y)); }
private static bool IsSquare(uint[] x) { uint[] z = Nat224.Create(); uint[] array = Nat224.Create(); Nat224.Copy(x, z); for (int i = 0; i < 7; i++) { Nat224.Copy(z, array); SecP224R1Field.SquareN(z, 1 << i, z); SecP224R1Field.Multiply(z, array, z); } SecP224R1Field.SquareN(z, 95, z); return(Nat224.IsOne(z)); }
private static bool IsSquare(uint[] x) { uint[] z = Nat224.Create(); uint[] numArray2 = Nat224.Create(); Nat224.Copy(x, z); for (int i = 0; i < 7; i++) { Nat224.Copy(z, numArray2); SecP224R1Field.SquareN(z, ((int)1) << i, z); SecP224R1Field.Multiply(z, numArray2, z); } SecP224R1Field.SquareN(z, 0x5f, z); return(Nat224.IsOne(z)); }
private static void RM(uint[] nc, uint[] d0, uint[] e0, uint[] d1, uint[] e1, uint[] f1) { uint[] t = Nat224.Create(); SecP224R1Field.Multiply(e1, e0, t); SecP224R1Field.Multiply(t, nc, t); SecP224R1Field.Multiply(d1, d0, f1); SecP224R1Field.Add(f1, t, f1); SecP224R1Field.Multiply(d1, e0, t); Nat224.Copy(f1, d1); SecP224R1Field.Multiply(e1, d0, e1); SecP224R1Field.Add(e1, t, e1); SecP224R1Field.Square(e1, f1); SecP224R1Field.Multiply(f1, nc, f1); }
private static bool IsSquare(uint[] x) { uint[] t1 = Nat224.Create(); uint[] t2 = Nat224.Create(); Nat224.Copy(x, t1); for (int i = 0; i < 7; ++i) { Nat224.Copy(t1, t2); SecP224R1Field.SquareN(t1, 1 << i, t1); SecP224R1Field.Multiply(t1, t2, t1); } SecP224R1Field.SquareN(t1, 95, t1); return(Nat224.IsOne(t1)); }
/** * return a sqrt root - the routine verifies that the calculation returns the right value - if * none exists it returns null. */ public override ECFieldElement Sqrt() { uint[] c = this.x; if (Nat224.IsZero(c) || Nat224.IsOne(c)) { return(this); } uint[] nc = Nat224.Create(); SecP224R1Field.Negate(c, nc); uint[] r = Mod.Random(SecP224R1Field.P); for (;;) { uint[] d1 = Nat224.Create(); Nat224.Copy(r, d1); uint[] e1 = Nat224.Create(); e1[0] = 1; uint[] f1 = Nat224.Create(); RP(nc, d1, e1, f1); uint[] d0 = Nat224.Create(); uint[] e0 = Nat224.Create(); for (int k = 1; k < 96; ++k) { Nat224.Copy(d1, d0); Nat224.Copy(e1, e0); RS(d1, e1, f1); if (Nat224.IsZero(d1)) { Mod.Invert(SecP224R1Field.P, e0, f1); SecP224R1Field.Multiply(f1, d0, f1); SecP224R1Field.Square(f1, d1); return(Nat224.Eq(c, d1) ? new SecP224R1FieldElement(f1) : null); } } // Avoid any possible infinite loop due to a bad random number generator SecP224R1Field.AddOne(r, r); } }
public override ECPoint Twice() { if (base.IsInfinity) { return(this); } ECCurve curve = this.Curve; SecP224K1FieldElement rawYCoord = (SecP224K1FieldElement)base.RawYCoord; if (rawYCoord.IsZero) { return(curve.Infinity); } SecP224K1FieldElement rawXCoord = (SecP224K1FieldElement)base.RawXCoord; SecP224K1FieldElement element3 = (SecP224K1FieldElement)base.RawZCoords[0]; uint[] z = Nat224.Create(); SecP224K1Field.Square(rawYCoord.x, z); uint[] numArray2 = Nat224.Create(); SecP224K1Field.Square(z, numArray2); uint[] numArray3 = Nat224.Create(); SecP224K1Field.Square(rawXCoord.x, numArray3); SecP224K1Field.Reduce32(Nat224.AddBothTo(numArray3, numArray3, numArray3), numArray3); uint[] numArray4 = z; SecP224K1Field.Multiply(z, rawXCoord.x, numArray4); SecP224K1Field.Reduce32(Nat.ShiftUpBits(7, numArray4, 2, 0), numArray4); uint[] numArray5 = Nat224.Create(); SecP224K1Field.Reduce32(Nat.ShiftUpBits(7, numArray2, 3, 0, numArray5), numArray5); SecP224K1FieldElement x = new SecP224K1FieldElement(numArray2); SecP224K1Field.Square(numArray3, x.x); SecP224K1Field.Subtract(x.x, numArray4, x.x); SecP224K1Field.Subtract(x.x, numArray4, x.x); SecP224K1FieldElement y = new SecP224K1FieldElement(numArray4); SecP224K1Field.Subtract(numArray4, x.x, y.x); SecP224K1Field.Multiply(y.x, numArray3, y.x); SecP224K1Field.Subtract(y.x, numArray5, y.x); SecP224K1FieldElement element6 = new SecP224K1FieldElement(numArray3); SecP224K1Field.Twice(rawYCoord.x, element6.x); if (!element3.IsOne) { SecP224K1Field.Multiply(element6.x, element3.x, element6.x); } return(new SecP224K1Point(curve, x, y, new ECFieldElement[] { element6 }, base.IsCompressed)); }
private static void RP(uint[] nc, uint[] d1, uint[] e1, uint[] f1, uint[] t) { Nat224.Copy(nc, f1); uint[] z = Nat224.Create(); uint[] numArray2 = Nat224.Create(); for (int i = 0; i < 7; i++) { Nat224.Copy(d1, z); Nat224.Copy(e1, numArray2); int num2 = ((int)1) << i; while (--num2 >= 0) { RS(d1, e1, f1, t); } RM(nc, z, numArray2, d1, e1, f1, t); } }
private static void RP(uint[] nc, uint[] d1, uint[] e1, uint[] f1, uint[] t) { Nat224.Copy(nc, f1); uint[] array = Nat224.Create(); uint[] array2 = Nat224.Create(); for (int i = 0; i < 7; i++) { Nat224.Copy(d1, array); Nat224.Copy(e1, array2); int num = 1 << i; while (--num >= 0) { SecP224R1FieldElement.RS(d1, e1, f1, t); } SecP224R1FieldElement.RM(nc, array, array2, d1, e1, f1, t); } }
public override ECPoint Lookup(int index) { uint[] x = Nat224.Create(), y = Nat224.Create(); int pos = 0; for (int i = 0; i < m_size; ++i) { uint MASK = (uint)(((i ^ index) - 1) >> 31); for (int j = 0; j < SECP224R1_FE_INTS; ++j) { x[j] ^= m_table[pos + j] & MASK; y[j] ^= m_table[pos + SECP224R1_FE_INTS + j] & MASK; } pos += (SECP224R1_FE_INTS * 2); } return(CreatePoint(x, y)); }
public virtual ECPoint Lookup(int index) { uint[] x = Nat224.Create(), y = Nat224.Create(); int pos = 0; for (int i = 0; i < m_size; ++i) { uint MASK = (uint)(((i ^ index) - 1) >> 31); for (int j = 0; j < SECP224K1_FE_INTS; ++j) { x[j] ^= m_table[pos + j] & MASK; y[j] ^= m_table[pos + SECP224K1_FE_INTS + j] & MASK; } pos += (SECP224K1_FE_INTS * 2); } return(m_outer.CreateRawPoint(new SecP224K1FieldElement(x), new SecP224K1FieldElement(y), false)); }
private static void RP(uint[] nc, uint[] d1, uint[] e1, uint[] f1, uint[] t) { Nat224.Copy(nc, f1); uint[] d0 = Nat224.Create(); uint[] e0 = Nat224.Create(); for (int i = 0; i < 7; ++i) { Nat224.Copy(d1, d0); Nat224.Copy(e1, e0); int j = 1 << i; while (--j >= 0) { RS(d1, e1, f1, t); } RM(nc, d0, e0, d1, e1, f1, t); } }
public override ECFieldElement Sqrt() { uint[] x = this.x; if (Nat224.IsZero(x) || Nat224.IsOne(x)) { return(this); } uint[] z = Nat224.Create(); SecP224R1Field.Negate(x, z); uint[] r = Mod.Random(SecP224R1Field.P); uint[] t = Nat224.Create(); if (!IsSquare(x)) { return(null); } while (!TrySqrt(z, r, t)) { SecP224R1Field.AddOne(r, r); } SecP224R1Field.Square(t, r); return(!Nat224.Eq(x, r) ? null : new SecP224R1FieldElement(t)); }
public override ECFieldElement Sqrt() { uint[] array = x; if (Nat224.IsZero(array) || Nat224.IsOne(array)) { return(this); } uint[] array2 = Nat224.Create(); SecP224R1Field.Negate(array, array2); uint[] array3 = Mod.Random(SecP224R1Field.P); uint[] t = Nat224.Create(); if (!IsSquare(array)) { return(null); } while (!TrySqrt(array2, array3, t)) { SecP224R1Field.AddOne(array3, array3); } SecP224R1Field.Square(t, array3); return((!Nat224.Eq(array, array3)) ? null : new SecP224R1FieldElement(t)); }
/** * return a sqrt root - the routine verifies that the calculation returns the right value - if * none exists it returns null. */ public override ECFieldElement Sqrt() { uint[] c = this.x; if (Nat224.IsZero(c) || Nat224.IsOne(c)) return this; uint[] nc = Nat224.Create(); SecP224R1Field.Negate(c, nc); uint[] r = Mod.Random(SecP224R1Field.P); uint[] t = Nat224.Create(); if (!IsSquare(c)) return null; while (!TrySqrt(nc, r, t)) { SecP224R1Field.AddOne(r, r); } SecP224R1Field.Square(t, r); return Nat224.Eq(c, r) ? new SecP224R1FieldElement(t) : null; }
private static bool TrySqrt(uint[] nc, uint[] r, uint[] t) { uint[] array = Nat224.Create(); Nat224.Copy(r, array); uint[] array2 = Nat224.Create(); array2[0] = 1u; uint[] array3 = Nat224.Create(); SecP224R1FieldElement.RP(nc, array, array2, array3, t); uint[] array4 = Nat224.Create(); uint[] z = Nat224.Create(); for (int i = 1; i < 96; i++) { Nat224.Copy(array, array4); Nat224.Copy(array2, z); SecP224R1FieldElement.RS(array, array2, array3, t); if (Nat224.IsZero(array)) { Mod.Invert(SecP224R1Field.P, z, t); SecP224R1Field.Multiply(t, array4, t); return(true); } } return(false); }
private static bool TrySqrt(uint[] nc, uint[] r, uint[] t) { uint[] z = Nat224.Create(); Nat224.Copy(r, z); uint[] numArray2 = Nat224.Create(); numArray2[0] = 1; uint[] numArray3 = Nat224.Create(); RP(nc, z, numArray2, numArray3, t); uint[] numArray4 = Nat224.Create(); uint[] numArray5 = Nat224.Create(); for (int i = 1; i < 0x60; i++) { Nat224.Copy(z, numArray4); Nat224.Copy(numArray2, numArray5); RS(z, numArray2, numArray3, t); if (Nat224.IsZero(z)) { Mod.Invert(SecP224R1Field.P, numArray5, t); SecP224R1Field.Multiply(t, numArray4, t); return(true); } } return(false); }
public override ECFieldElement Multiply(ECFieldElement b) { uint[] z = Nat224.Create(); SecP224R1Field.Multiply(x, ((SecP224R1FieldElement)b).x, z); return(new SecP224R1FieldElement(z)); }
public override ECFieldElement Subtract(ECFieldElement b) { uint[] z = Nat224.Create(); SecP224R1Field.Subtract(x, ((SecP224R1FieldElement)b).x, z); return(new SecP224R1FieldElement(z)); }
public override ECFieldElement AddOne() { uint[] z = Nat224.Create(); SecP224R1Field.AddOne(x, z); return(new SecP224R1FieldElement(z)); }
public SecP224R1FieldElement() { this.x = Nat224.Create(); }
/** * return a sqrt root - the routine verifies that the calculation returns the right value - if * none exists it returns null. */ public override ECFieldElement Sqrt() { /* * Q == 8m + 5, so we use Pocklington's method for this case. * * First, raise this element to the exponent 2^221 - 2^29 - 2^9 - 2^8 - 2^6 - 2^4 - 2^1 (i.e. m + 1) * * Breaking up the exponent's binary representation into "repunits", we get: * { 191 1s } { 1 0s } { 19 1s } { 2 0s } { 1 1s } { 1 0s } { 1 1s } { 1 0s } { 3 1s } { 1 0s } * * Therefore we need an addition chain containing 1, 3, 19, 191 (the lengths of the repunits) * We use: [1], 2, [3], 4, 8, 11, [19], 23, 42, 84, 107, [191] */ uint[] x1 = this.x; if (Nat224.IsZero(x1) || Nat224.IsOne(x1)) { return(this); } uint[] x2 = Nat224.Create(); SecP224K1Field.Square(x1, x2); SecP224K1Field.Multiply(x2, x1, x2); uint[] x3 = x2; SecP224K1Field.Square(x2, x3); SecP224K1Field.Multiply(x3, x1, x3); uint[] x4 = Nat224.Create(); SecP224K1Field.Square(x3, x4); SecP224K1Field.Multiply(x4, x1, x4); uint[] x8 = Nat224.Create(); SecP224K1Field.SquareN(x4, 4, x8); SecP224K1Field.Multiply(x8, x4, x8); uint[] x11 = Nat224.Create(); SecP224K1Field.SquareN(x8, 3, x11); SecP224K1Field.Multiply(x11, x3, x11); uint[] x19 = x11; SecP224K1Field.SquareN(x11, 8, x19); SecP224K1Field.Multiply(x19, x8, x19); uint[] x23 = x8; SecP224K1Field.SquareN(x19, 4, x23); SecP224K1Field.Multiply(x23, x4, x23); uint[] x42 = x4; SecP224K1Field.SquareN(x23, 19, x42); SecP224K1Field.Multiply(x42, x19, x42); uint[] x84 = Nat224.Create(); SecP224K1Field.SquareN(x42, 42, x84); SecP224K1Field.Multiply(x84, x42, x84); uint[] x107 = x42; SecP224K1Field.SquareN(x84, 23, x107); SecP224K1Field.Multiply(x107, x23, x107); uint[] x191 = x23; SecP224K1Field.SquareN(x107, 84, x191); SecP224K1Field.Multiply(x191, x84, x191); uint[] t1 = x191; SecP224K1Field.SquareN(t1, 20, t1); SecP224K1Field.Multiply(t1, x19, t1); SecP224K1Field.SquareN(t1, 3, t1); SecP224K1Field.Multiply(t1, x1, t1); SecP224K1Field.SquareN(t1, 2, t1); SecP224K1Field.Multiply(t1, x1, t1); SecP224K1Field.SquareN(t1, 4, t1); SecP224K1Field.Multiply(t1, x3, t1); SecP224K1Field.Square(t1, t1); uint[] t2 = x84; SecP224K1Field.Square(t1, t2); if (Nat224.Eq(x1, t2)) { return(new SecP224K1FieldElement(t1)); } /* * If the first guess is incorrect, we multiply by a precomputed power of 2 to get the second guess, * which is ((4x)^(m + 1))/2 mod Q */ SecP224K1Field.Multiply(t1, PRECOMP_POW2, t1); SecP224K1Field.Square(t1, t2); if (Nat224.Eq(x1, t2)) { return(new SecP224K1FieldElement(t1)); } return(null); }
public override ECFieldElement Add(ECFieldElement b) { uint[] z = Nat224.Create(); SecP224K1Field.Add(x, ((SecP224K1FieldElement)b).x, z); return(new SecP224K1FieldElement(z)); }