public static void secp256k1_ge_set_all_gej_var(Ge[] r, GeJ[] a, int len, EventHandler <Callback> cb) { Fe[] a1 = new Fe[len]; int len1 = 0; for (int index = 0; index < len; ++index) { if (!a[index].Infinity) { a1[len1++] = a[index].Z.Clone(); } } Fe[] r1 = new Fe[len1]; Field.InvAllVar(r1, a1, len1); int num = 0; for (int index = 0; index < len; ++index) { r[index].Infinity = a[index].Infinity; if (!a[index].Infinity) { Group.secp256k1_ge_set_gej_zinv(r[index], a[index], r1[num++]); } } }
public static void secp256k1_ge_set_table_gej_var(Ge[] r, GeJ[] a, Fe[] zr, int len) { int index = len - 1; Fe fe = new Fe(); if (len <= 0) { return; } Field.Inv(fe, a[index].Z); Group.secp256k1_ge_set_gej_zinv(r[index], a[index], fe); while (index > 0) { Field.Mul(fe, fe, zr[index]); --index; Group.secp256k1_ge_set_gej_zinv(r[index], a[index], fe); } }
// // /** Double multiply: R = na*A + ng*G */ // // static void secp256k1_ecmult(const secp256k1_ecmult_context* ctx, secp256k1_gej* r, const secp256k1_gej* a, const secp256k1_scalar* na, const secp256k1_scalar* ng); //#if defined(EXHAUSTIVE_TEST_ORDER) ///* We need to lower these values for exhaustive tests because // * the tables cannot have infinities in them (this breaks the // * affine-isomorphism stuff which tracks z-ratios) */ //#if EXHAUSTIVE_TEST_ORDER > 128 //#define WINDOW_A 5 //#define WINDOW_G 8 //#elif EXHAUSTIVE_TEST_ORDER > 8 //#define WINDOW_A 4 //#define WINDOW_G 4 //#else //#define WINDOW_A 2 //#define WINDOW_G 2 //#endif //#else // /* optimal for 128-bit and 256-bit exponents. */ //#define WINDOW_A 5 // /** larger numbers may result in slightly better performance, at the cost of // exponentially larger precomputed tables. */ //# ifdef USE_ENDOMORPHISM // /** Two tables for window size 15: 1.375 MiB. */ //#define WINDOW_G 15 //#else // /** One table for window size 16: 1.375 MiB. */ //#define WINDOW_G 16 //#endif //#endif /** The number of entries a table with precomputed multiples needs to have. */ //#define ECMULT_TABLE_SIZE(w) (1 << ((w)-2)) /// <summary> /// Fill a table 'prej' with precomputed odd multiples of a. Prej will contain /// the values [1*a,3*a,...,(2*n-1)*a], so it space for n values. zr[0] will /// contain prej[0].z / a.z. The other zr[i] values = prej[i].z / prej[i-1].z. /// Prej's Z values are undefined, except for the last value. /// </summary> /// <param name="n"></param> /// <param name="prej"></param> /// <param name="zr"></param> /// <param name="a"></param> static void secp256k1_ecmult_odd_multiples_table(int n, GeJ[] prej, Fe[] zr, GeJ a) { Debug.Assert(!a.Infinity); GeJ d = new GeJ(); Group.secp256k1_gej_double_var(d, a, null); /* * Perform the additions on an isomorphism where 'd' is affine: drop the z coordinate * of 'd', and scale the 1P starting value's x/y coordinates without changing its z. */ Ge dGe = new Ge(); dGe.X = d.X.Clone(); dGe.Y = d.Y.Clone(); dGe.Infinity = false; Ge aGe = new Ge(); Group.secp256k1_ge_set_gej_zinv(aGe, a, d.Z); prej[0].X = aGe.X.Clone(); prej[0].Y = aGe.Y.Clone(); prej[0].Z = a.Z.Clone(); prej[0].Infinity = false; zr[0] = d.Z.Clone(); for (var i = 1; i < n; i++) { Group.secp256k1_gej_add_ge_var(prej[i], prej[i - 1], dGe, zr[i]); } /* * Each point in 'prej' has a z coordinate too small by a factor of 'd.z'. Only * the final point's z coordinate is actually used though, so just update that. */ Field.Mul(prej[n - 1].Z, prej[n - 1].Z, d.Z); }
private static void secp256k1_ecmult_odd_multiples_table(int n, GeJ[] prej, Fe[] zr, GeJ a) { GeJ r1 = new GeJ(); Group.secp256k1_gej_double_var(r1, a, (Fe)null); Ge b = new Ge(); b.X = r1.X.Clone(); b.Y = r1.Y.Clone(); b.Infinity = false; Ge r2 = new Ge(); Group.secp256k1_ge_set_gej_zinv(r2, a, r1.Z); prej[0].X = r2.X.Clone(); prej[0].Y = r2.Y.Clone(); prej[0].Z = a.Z.Clone(); prej[0].Infinity = false; zr[0] = r1.Z.Clone(); for (int index = 1; index < n; ++index) { Group.secp256k1_gej_add_ge_var(prej[index], prej[index - 1], b, zr[index]); } Field.Mul(prej[n - 1].Z, prej[n - 1].Z, r1.Z); }