private static bool secp256k1_ecdsa_sig_sign(secp256k1_ecmult_gen_context ctx, secp256k1_scalar sigr, secp256k1_scalar sigs, secp256k1_scalar seckey, secp256k1_scalar message, secp256k1_scalar nonce, out byte recid) { var b = new byte[32]; secp256k1_gej rp; secp256k1_ge r = new secp256k1_ge(); secp256k1_scalar n = new secp256k1_scalar(); bool overflow = false; ECMultGen.secp256k1_ecmult_gen(ctx, out rp, nonce); Group.secp256k1_ge_set_gej(r, rp); Field.secp256k1_fe_normalize(r.x); Field.secp256k1_fe_normalize(r.y); Field.secp256k1_fe_get_b32(b, r.x); Scalar.secp256k1_scalar_set_b32(sigr, b, ref overflow); /* These two conditions should be checked before calling */ Util.VERIFY_CHECK(!Scalar.secp256k1_scalar_is_zero(sigr)); Util.VERIFY_CHECK(!overflow); // The overflow condition is cryptographically unreachable as hitting it requires finding the discrete log // of some P where P.x >= order, and only 1 in about 2^127 points meet this criteria. recid = (byte)((overflow ? 2 : 0) | (Field.secp256k1_fe_is_odd(r.y) ? 1 : 0)); Scalar.secp256k1_scalar_mul(n, sigr, seckey); Scalar.secp256k1_scalar_add(n, n, message); Scalar.secp256k1_scalar_inverse(sigs, nonce); Scalar.secp256k1_scalar_mul(sigs, sigs, n); Scalar.secp256k1_scalar_clear(n); Group.secp256k1_gej_clear(rp); Group.secp256k1_ge_clear(r); if (Scalar.secp256k1_scalar_is_zero(sigs)) { return(false); } if (Scalar.secp256k1_scalar_is_high(sigs)) { Scalar.secp256k1_scalar_negate(sigs, sigs); recid ^= 1; } return(true); }
public secp256k1_context_struct() { ecmult_ctx = new secp256k1_ecmult_context(); ecmult_gen_ctx = new secp256k1_ecmult_gen_context(); }
public static void secp256k1_ecmult_gen_context_init(secp256k1_ecmult_gen_context ctx) { ctx.prec = null; }
public static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context ctx, EventHandler <secp256k1_callback> cb) { #if !USE_ECMULT_STATIC_PRECOMPUTATION secp256k1_ge[] prec = new secp256k1_ge[1024]; secp256k1_gej gj = new secp256k1_gej(); secp256k1_gej nums_gej = new secp256k1_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.secp256k1_ge_const_g); /* Construct a group element with no known corresponding scalar (nothing up my sleeve). */ { var nums_b32 = Encoding.UTF8.GetBytes("The scalar for this x is unknown"); secp256k1_fe nums_x = new secp256k1_fe(); secp256k1_ge nums_ge = new secp256k1_ge(); var r = Field.secp256k1_fe_set_b32(nums_x, nums_b32); //(void)r; Util.VERIFY_CHECK(r); r = Group.secp256k1_ge_set_xo_var(nums_ge, nums_x, false); //(void)r; Util.VERIFY_CHECK(r); Group.secp256k1_gej_set_ge(nums_gej, nums_ge); /* Add G to make the bits in x uniformly distributed. */ Group.secp256k1_gej_add_ge_var(nums_gej, nums_gej, Group.secp256k1_ge_const_g, null); } /* compute prec. */ { secp256k1_gej[] precj = new secp256k1_gej[1024]; /* Jacobian versions of prec. */ for (int k = 0; k < precj.Length; k++) { precj[k] = new secp256k1_gej(); } secp256k1_gej gbase; secp256k1_gej numsbase; gbase = gj.Clone(); /* 16^j * G */ numsbase = nums_gej.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, nums_gej, null); } } for (int k = 0; k < prec.Length; k++) { prec[k] = new secp256k1_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.secp256k1_ge_to_storage(ctx.prec[j][i], prec[j * 16 + i]); } } #else (void)cb; ctx.prec = (secp256k1_ge_storage(*)[64][16])secp256k1_ecmult_static_context;