private static bool Secp256K1EcdsaSigSign(EcmultGenContext ctx, Scalar sigr, Scalar sigs, Scalar seckey, Scalar message, Scalar nonce, out byte recid) { byte[] numArray = new byte[32]; Ge r1 = new Ge(); Scalar scalar = new Scalar(); bool overflow = false; GeJ r2; EcMultGen.secp256k1_ecmult_gen(ctx, out r2, nonce); Group.SetGeJ(r1, r2); Field.Normalize(r1.X); Field.Normalize(r1.Y); Field.GetB32(numArray, r1.X); Scalar.SetB32(sigr, numArray, ref overflow); recid = (byte)((overflow ? 2 : 0) | (Field.IsOdd(r1.Y) ? 1 : 0)); Scalar.Mul(scalar, sigr, seckey); Scalar.Add(scalar, scalar, message); Scalar.Inverse(sigs, nonce); Scalar.Mul(sigs, sigs, scalar); Scalar.Clear(scalar); Group.secp256k1_gej_clear(r2); Group.secp256k1_ge_clear(r1); if (Scalar.IsZero(sigs)) { return(false); } if (Scalar.IsHigh(sigs)) { Scalar.Negate(sigs, sigs); recid ^= (byte)1; } return(true); }
private static bool Secp256K1EcdsaSigSign(EcmultGenContext ctx, Scalar sigr, Scalar sigs, Scalar seckey, Scalar message, Scalar nonce, out byte recid) { var b = new byte[32]; GeJ rp; Ge r = new Ge(); Scalar n = new Scalar(); bool overflow = false; EcMultGen.secp256k1_ecmult_gen(ctx, out rp, nonce); Group.SetGeJ(r, rp); Field.Normalize(r.X); Field.Normalize(r.Y); Field.GetB32(b, r.X); Scalar.SetB32(sigr, b, ref overflow); /* These two conditions should be checked before calling */ Debug.Assert(!Scalar.IsZero(sigr)); Debug.Assert(!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.IsOdd(r.Y) ? 1 : 0)); Scalar.Mul(n, sigr, seckey); Scalar.Add(n, n, message); Scalar.Inverse(sigs, nonce); Scalar.Mul(sigs, sigs, n); Scalar.Clear(n); Group.secp256k1_gej_clear(rp); Group.secp256k1_ge_clear(r); if (Scalar.IsZero(sigs)) { return(false); } if (Scalar.IsHigh(sigs)) { Scalar.Negate(sigs, sigs); recid ^= 1; } return(true); }