internal static bool Pubkey_parse(ReadOnlySpan <byte> pub, out bool compressed, out GE elem) { compressed = false; elem = default; if (pub.Length == 33 && (pub[0] == SECP256K1_TAG_PUBKEY_EVEN || pub[0] == SECP256K1_TAG_PUBKEY_ODD)) { compressed = true; return (FE.TryCreate(pub.Slice(1), out var x) && GE.TryCreateXOVariable(x, pub[0] == SECP256K1_TAG_PUBKEY_ODD, out elem)); } else if (pub.Length == 65 && (pub[0] == SECP256K1_TAG_PUBKEY_UNCOMPRESSED || pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_EVEN || pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_ODD)) { if (!FE.TryCreate(pub.Slice(1), out var x) || !FE.TryCreate(pub.Slice(33), out var y)) { return(false); } elem = new GE(x, y); if ((pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_EVEN || pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_ODD) && y.IsOdd != (pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_ODD)) { return(false); } return(elem.IsValidVariable); } else { return(false); } }
public ECMultGenContext() { Span <GE> prec = stackalloc GE[1024]; GEJ gj; GEJ nums_gej; int i, j; this.prec = new GEStorage[64, 16]; gj = EC.G.ToGroupElementJacobian(); /* Construct a group element with no known corresponding scalar (nothing up my sleeve). */ { var nums_b32 = "The scalar for this x is unknown".ToCharArray().Select(b => (byte)b).ToArray(); FE nums_x; GE nums_ge; var r = FE.TryCreate(nums_b32, out nums_x); VERIFY_CHECK(r); r = GE.TryCreateXOVariable(nums_x, false, out nums_ge); VERIFY_CHECK(r); nums_gej = nums_ge.ToGroupElementJacobian(); /* Add G to make the bits in x uniformly distributed. */ nums_gej = nums_gej.AddVariable(EC.G, out _); } /* compute prec. */ { Span <GEJ> precj = stackalloc GEJ[1024]; /* Jacobian versions of prec. */ GEJ gbase; GEJ numsbase; gbase = gj; /* 16^j * G */ numsbase = nums_gej; /* 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; for (i = 1; i < 16; i++) { precj[j * 16 + i] = precj[j * 16 + i - 1].AddVariable(gbase, out _); } /* Multiply gbase by 16. */ for (i = 0; i < 4; i++) { gbase = gbase.DoubleVariable(); } /* Multiply numbase by 2. */ numsbase = numsbase.DoubleVariable(); if (j == 62) { /* In the last iteration, numsbase is (1 - 2^j) * nums instead. */ numsbase = numsbase.Negate(); numsbase = numsbase.AddVariable(nums_gej, out _); } } GE.SetAllGroupElementJacobianVariable(prec, precj, 1024); } for (j = 0; j < 64; j++) { for (i = 0; i < 16; i++) { this.prec[j, i] = prec[j * 16 + i].ToStorage(); } } Blind(); }