예제 #1
0
        public static void crypto_sign2(Span <byte> sig, ReadOnlySpan <byte> m, ReadOnlySpan <byte> sk)
        {
            var hasher = new Sha512();
            {
                hasher.Update(sk.Slice(0, 32));
                Span <byte> az = stackalloc byte[64];
                hasher.Finish(az);
                ScalarOperations.sc_clamp(az);

                hasher.Init();
                hasher.Update(az.Slice(32, 32));
                hasher.Update(m);
                Span <byte> r = stackalloc byte[64];
                hasher.Finish(r);

                ScalarOperations.sc_reduce(r);
                GroupOperations.ge_scalarmult_base(out var R, r);
                GroupOperations.ge_p3_tobytes(sig, in R);

                hasher.Init();
                hasher.Update(sig.Slice(0, 32));
                hasher.Update(sk.Slice(32, 32));
                hasher.Update(m);
                Span <byte> hram = stackalloc byte[64];
                hasher.Finish(hram);

                ScalarOperations.sc_reduce(hram);
                ScalarOperations.sc_muladd(sig.Slice(32, 32), hram, az, r);
            }
        }
예제 #2
0
        public static bool crypto_sign_verify(ReadOnlySpan <byte> sig, ReadOnlySpan <byte> m, ReadOnlySpan <byte> pk)
        {
            if ((sig[63] & 224) != 0)
            {
                return(false);
            }
            if (GroupOperations.ge_frombytes_negate_vartime(out var A, pk) != 0)
            {
                return(false);
            }

            var hasher = new Sha512();

            hasher.Update(sig.Slice(0, 32));
            hasher.Update(pk.Slice(0, 32));
            hasher.Update(m);
            Span <byte> h = stackalloc byte[64];

            hasher.Finish(h);

            ScalarOperations.sc_reduce(h);

            GroupOperations.ge_double_scalarmult_vartime(out var R, h, in A, sig.Slice(32, 32));
            Span <byte> checkr = stackalloc byte[32];

            GroupOperations.ge_tobytes(checkr, in R);
            var result = CryptoBytes.ConstantTimeEquals(checkr, sig, 32);

            CryptoBytes.Wipe(h);
            CryptoBytes.Wipe(checkr);
            return(result);
        }
예제 #3
0
        public static void crypto_sign_keypair(Span <byte> pk, Span <byte> sk, ReadOnlySpan <byte> seed)
        {
            Sha512.Hash(seed, sk);

            ScalarOperations.sc_clamp(sk);

            GroupOperations.ge_scalarmult_base(out var A, sk.Slice(0, 32));
            GroupOperations.ge_p3_tobytes(pk, in A);

            seed.CopyTo(sk);
            pk.CopyTo(sk.Slice(32, 32));
        }