public static void ContextBuild(EcmultGenContext ctx, EventHandler <Callback> cb) { Ge[] r1 = new Ge[1024]; GeJ r2 = new GeJ(); GeJ geJ1 = new GeJ(); if (ctx.Prec != null) { return; } ctx.PrecInit(); Group.secp256k1_gej_set_ge(r2, Group.Secp256K1GeConstG); byte[] bytes = Encoding.UTF8.GetBytes("The scalar for this x is unknown"); Fe fe = new Fe(); Ge ge = new Ge(); Field.SetB32(fe, bytes); Group.secp256k1_ge_set_xo_var(ge, fe, false); Group.secp256k1_gej_set_ge(geJ1, ge); Group.secp256k1_gej_add_ge_var(geJ1, geJ1, Group.Secp256K1GeConstG, (Fe)null); GeJ[] a = new GeJ[1024]; for (int index = 0; index < a.Length; ++index) { a[index] = new GeJ(); } GeJ geJ2 = r2.Clone(); GeJ geJ3 = geJ1.Clone(); for (int index1 = 0; index1 < 64; ++index1) { a[index1 * 16] = geJ3.Clone(); for (int index2 = 1; index2 < 16; ++index2) { Group.secp256k1_gej_add_var(a[index1 * 16 + index2], a[index1 * 16 + index2 - 1], geJ2, (Fe)null); } for (int index2 = 0; index2 < 4; ++index2) { Group.secp256k1_gej_double_var(geJ2, geJ2, (Fe)null); } Group.secp256k1_gej_double_var(geJ3, geJ3, (Fe)null); if (index1 == 62) { Group.secp256k1_gej_neg(geJ3, geJ3); Group.secp256k1_gej_add_var(geJ3, geJ3, geJ1, (Fe)null); } } for (int index = 0; index < r1.Length; ++index) { r1[index] = new Ge(); } Group.secp256k1_ge_set_all_gej_var(r1, a, 1024, cb); for (int index1 = 0; index1 < 64; ++index1) { for (int index2 = 0; index2 < 16; ++index2) { Group.ToStorage(ctx.Prec[index1][index2], r1[index1 * 16 + index2]); } } EcMultGen.Blind(ctx, (byte[])null); }
public static void secp256k1_ecmult_odd_multiples_table_storage_var(int n, GeStorage[] pre, GeJ a, EventHandler <Callback> cb) { GeJ[] geJArray = new GeJ[n]; Ge[] r = new Ge[n]; Fe[] zr = new Fe[n]; for (int index = 0; index < n; ++index) { geJArray[index] = new GeJ(); r[index] = new Ge(); zr[index] = new Fe(); } EcMult.secp256k1_ecmult_odd_multiples_table(n, geJArray, zr, a); Group.secp256k1_ge_set_table_gej_var(r, geJArray, zr, n); for (int index = 0; index < n; ++index) { Group.ToStorage(pre[index], r[index]); } }
///** Fill a table 'pre' with precomputed odd multiples of a. // * // * There are two versions of this function: // * - secp256k1_ecmult_odd_multiples_table_globalz_windowa which brings its // * resulting point set to a single constant Z denominator, stores the X and Y // * coordinates as ge_storage points in pre, and stores the global Z in rz. // * It only operates on tables sized for WINDOW_A wnaf multiples. // * - secp256k1_ecmult_odd_multiples_table_storage_var, which converts its // * resulting point set to actually affine points, and stores those in pre. // * It operates on tables of any size, but uses heap-allocated temporaries. // * // * To compute a*P + b*G, we compute a table for P using the first function, // * and for G using the second (which requires an inverse, but it only needs to // * happen once). // */ //static void secp256k1_ecmult_odd_multiples_table_globalz_windowa(secp256k1_ge* pre, secp256k1_fe* globalz, const secp256k1_gej* a) //{ // secp256k1_gej prej[ECMULT_TABLE_SIZE(WINDOW_A)]; // secp256k1_fe zr[ECMULT_TABLE_SIZE(WINDOW_A)]; // /* Compute the odd multiples in Jacobian form. */ // secp256k1_ecmult_odd_multiples_table(ECMULT_TABLE_SIZE(WINDOW_A), prej, zr, a); // /* Bring them to the same Z denominator. */ // secp256k1_ge_globalz_set_table_gej(ECMULT_TABLE_SIZE(WINDOW_A), pre, globalz, prej, zr); //} public static void secp256k1_ecmult_odd_multiples_table_storage_var(int n, GeStorage[] pre, GeJ a, EventHandler <Callback> cb) { GeJ[] prej = new GeJ[n]; Ge[] prea = new Ge[n]; Fe[] zr = new Fe[n]; for (int i = 0; i < n; i++) { prej[i] = new GeJ(); prea[i] = new Ge(); zr[i] = new Fe(); } /* Compute the odd multiples in Jacobian form. */ secp256k1_ecmult_odd_multiples_table(n, prej, zr, a); /* Convert them in batch to affine coordinates. */ Group.secp256k1_ge_set_table_gej_var(prea, prej, zr, n); /* Convert them to compact storage form. */ for (var i = 0; i < n; i++) { Group.ToStorage(pre[i], prea[i]); } }
public static void ContextBuild(EcmultGenContext ctx, EventHandler <Callback> cb) { #if !USE_ECMULT_STATIC_PRECOMPUTATION Ge[] prec = new Ge[1024]; GeJ gj = new GeJ(); GeJ numsGej = new GeJ(); int i, j; #endif if (ctx.Prec != null) { return; } #if !USE_ECMULT_STATIC_PRECOMPUTATION ctx.PrecInit(); /* get the generator */ Group.secp256k1_gej_set_ge(gj, Group.Secp256K1GeConstG); /* Construct a group element with no known corresponding scalar (nothing up my sleeve). */ { var numsB32 = Encoding.UTF8.GetBytes("The scalar for this x is unknown"); Fe numsX = new Fe(); Ge numsGe = new Ge(); var r = Field.SetB32(numsX, numsB32); //(void)r; Util.VERIFY_CHECK(r); r = Group.secp256k1_ge_set_xo_var(numsGe, numsX, false); //(void)r; Util.VERIFY_CHECK(r); Group.secp256k1_gej_set_ge(numsGej, numsGe); /* Add G to make the bits in x uniformly distributed. */ Group.secp256k1_gej_add_ge_var(numsGej, numsGej, Group.Secp256K1GeConstG, null); } /* compute prec. */ { GeJ[] precj = new GeJ[1024]; /* Jacobian versions of prec. */ for (int k = 0; k < precj.Length; k++) { precj[k] = new GeJ(); } GeJ gbase; GeJ numsbase; gbase = gj.Clone(); /* 16^j * G */ numsbase = numsGej.Clone(); /* 2^j * nums. */ for (j = 0; j < 64; j++) { /* Set precj[j*16 .. j*16+15] to (numsbase, numsbase + gbase, ..., numsbase + 15*gbase). */ precj[j * 16] = numsbase.Clone(); for (i = 1; i < 16; i++) { Group.secp256k1_gej_add_var(precj[j * 16 + i], precj[j * 16 + i - 1], gbase, null); } /* Multiply gbase by 16. */ for (i = 0; i < 4; i++) { Group.secp256k1_gej_double_var(gbase, gbase, null); } /* Multiply numbase by 2. */ Group.secp256k1_gej_double_var(numsbase, numsbase, null); if (j == 62) { /* In the last iteration, numsbase is (1 - 2^j) * nums instead. */ Group.secp256k1_gej_neg(numsbase, numsbase); Group.secp256k1_gej_add_var(numsbase, numsbase, numsGej, null); } } for (int k = 0; k < prec.Length; k++) { prec[k] = new Ge(); } Group.secp256k1_ge_set_all_gej_var(prec, precj, 1024, cb); } for (j = 0; j < 64; j++) { for (i = 0; i < 16; i++) { Group.ToStorage(ctx.Prec[j][i], prec[j * 16 + i]); } } #else (void)cb; ctx.prec = (secp256k1_ge_storage(*)[64][16])secp256k1_ecmult_static_context;