Esempio n. 1
0
 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);
     }
 }
        internal static void secp256k1_xonly_ge_serialize(Span <byte> output32, ref GE ge)
        {
            if (ge.IsInfinity)
            {
                throw new InvalidOperationException("ge should not be infinite");
            }

            ge = ge.NormalizeXVariable();
            ge.x.WriteToSpan(output32);
        }
        public static void SetAllGroupElementJacobianVariable(Span <GE> r, ReadOnlySpan <GEJ> a, int len)
        {
            FE  u;
            int i;
            int last_i = SIZE_MAX;

            for (i = 0; i < len; i++)
            {
                if (!a[i].infinity)
                {
                    /* Use destination's x coordinates as scratch space */
                    if (last_i == SIZE_MAX)
                    {
                        r[i] = new GE(a[i].z, r[i].y, r[i].infinity);
                    }
                    else
                    {
                        FE rx = r[last_i].x * a[i].z;
                        r[i] = new GE(rx, r[i].y, r[i].infinity);
                    }
                    last_i = i;
                }
            }
            if (last_i == SIZE_MAX)
            {
                return;
            }
            u = r[last_i].x.InverseVariable();

            i = last_i;
            while (i > 0)
            {
                i--;
                if (!a[i].infinity)
                {
                    FE rx = r[i].x * u;
                    r[last_i] = new GE(rx, r[last_i].y, r[last_i].infinity);
                    u         = u * a[last_i].z;
                    last_i    = i;
                }
            }
            VERIFY_CHECK(!a[last_i].infinity);
            r[last_i] = new GE(u, r[last_i].y, r[last_i].infinity);

            for (i = 0; i < len; i++)
            {
                r[i] = new GE(r[i].x, r[i].y, a[i].infinity);
                if (!a[i].infinity)
                {
                    r[i] = a[i].ToGroupElementZInv(r[i].x);
                }
            }
        }
        public static bool TryCreateXOVariable(FE x, bool odd, out GE result)
        {
            if (!TryCreateXQuad(x, out result))
            {
                return(false);
            }
            var ry = result.y.NormalizeVariable();

            if (ry.IsOdd != odd)
            {
                ry = ry.Negate(1);
            }
            result = new GE(result.x, ry, result.infinity);
            return(true);
        }
        public static bool TryCreateXQuad(FE x, out GE result)
        {
            result = GE.Zero;
            FE   rx, ry;
            bool rinfinity;
            FE   x2, x3, c;

            rx        = x;
            x2        = x.Sqr();
            x3        = x * x2;
            rinfinity = false;
            c         = new FE(EC.CURVE_B);
            c        += x3;
            if (!c.Sqrt(out ry))
            {
                return(false);
            }
            result = new GE(rx, ry, rinfinity);
            return(true);
        }
Esempio n. 6
0
 internal static bool Pubkey_parse(ReadOnlySpan <byte> pub, out GE elem)
 {
     return(Pubkey_parse(pub, out _, out elem));
 }
Esempio n. 7
0
        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();
        }