示例#1
0
 private unsafe void EnsureInitialized()
 {
     if (k == default)
     {
         k = (byte *)Libsodium.sodium_malloc(Aead.KeySize);
     }
 }
示例#2
0
        /// <summary>
        /// Initializes a new SymmetricState with an
        /// arbitrary-length protocolName byte sequence.
        /// </summary>
        public SymmetricState(ReadOnlySpan <byte> protocolName)
        {
            int length = hash.HashLen;

            unsafe
            {
                ck = (byte *)Libsodium.sodium_malloc((ulong)length);
            }

            h = new byte[length];

            if (protocolName.Length <= length)
            {
                protocolName.CopyTo(h);
            }
            else
            {
                hash.AppendData(protocolName);
                hash.GetHashAndReset(h);
            }

            unsafe
            {
                for (var i = 0; i < length; i++)
                {
                    ck[i] = h[i];
                }
            }
        }
示例#3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="KeyPair"/> class.
        /// </summary>
        /// <param name="privateKey">The private key.</param>
        /// <param name="privateKeyLen">The length of the private key.</param>
        /// <param name="publicKey">The public key.</param>
        /// <exception cref="ArgumentNullException">
        /// Thrown if the <paramref name="privateKey"/> or the <paramref name="publicKey"/> is null.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// Thrown if the lengths of the <paramref name="privateKey"/> or the <paramref name="publicKey"/> are invalid.
        /// </exception>
        public unsafe KeyPair(byte *privateKey, int privateKeyLen, byte[] publicKey)
        {
            Exceptions.ThrowIfNull(privateKey, nameof(privateKey));
            Exceptions.ThrowIfNull(publicKey, nameof(publicKey));

            if (privateKeyLen != 32)
            {
                throw new ArgumentException("Private key must have length of 32 bytes.", nameof(privateKey));
            }

            if (publicKey.Length != 32)
            {
                throw new ArgumentException("Public key must have length of 32 bytes.", nameof(publicKey));
            }

            var privateKeyCopy = (byte *)Libsodium.sodium_malloc((ulong)privateKeyLen);

            for (var i = 0; i < privateKeyLen; i++)
            {
                privateKeyCopy[i] = privateKey[i];
            }

            this.privateKey = privateKeyCopy;
            this.publicKey  = publicKey;
        }
示例#4
0
 /// <summary>
 /// Creates a new pre-shared key of a given length.
 /// The key is filled with random, non-zero bytes in a cryptographically secure fashion.
 /// </summary>
 /// <param name="size">Tge size of the key to generate.</param>
 /// <returns></returns>
 public static PskRef Create(uint size = Aead.KeySize)
 {
     unsafe
     {
         var ptr = (byte *)Libsodium.sodium_malloc(size);
         Libsodium.randombytes_buf(ptr, size);
         return(new PskRef(ptr, size));
     }
 }
示例#5
0
        public KeyPair GenerateKeyPair()
        {
            var privateKey = Utilities.GetRandomBytes(DhLen);
            var publicKey  = new byte[DhLen];

            Libsodium.crypto_scalarmult_curve25519_base(publicKey, privateKey);

            return(new KeyPair(privateKey, publicKey));
        }
示例#6
0
        /// <summary>
        /// Creates a new pre-shared key based on an existing pointer.
        /// This allocates a new copy of the existing key, which protects against disposal of the cloned key.
        /// </summary>
        /// <param name="buffer">A reference to the existing key.</param>
        /// <param name="len">The length of the existing key to copy into the new key.</param>
        /// <returns></returns>
        public static unsafe PskRef Create(byte *buffer, uint len = Aead.KeySize)
        {
            var b = (byte *)Libsodium.sodium_malloc(len);

            for (var i = 0; i < len; i++)
            {
                b[i] = buffer[i];
            }
            return(new PskRef(b, len));
        }
示例#7
0
 public unsafe void AppendData(byte *data, int dataLen)
 {
     if (dataLen > 0)
     {
         Libsodium.crypto_hash_sha256_update(
             state,
             data,
             (ulong)dataLen
             );
     }
 }
示例#8
0
 public void AppendData(ReadOnlySpan <byte> data)
 {
     if (!data.IsEmpty)
     {
         Libsodium.crypto_generichash_blake2b_update(
             aligned,
             ref MemoryMarshal.GetReference(data),
             (ulong)data.Length
             );
     }
 }
示例#9
0
        public KeyPair GenerateKeyPair(ReadOnlySpan <byte> privateKey)
        {
            Debug.Assert(privateKey.Length == DhLen);

            var privateKeyCopy = privateKey.ToArray();
            var publicKey      = new byte[DhLen];

            Libsodium.crypto_scalarmult_curve25519_base(publicKey, privateKeyCopy);

            return(new KeyPair(privateKeyCopy, publicKey));
        }
示例#10
0
 public unsafe void AppendData(byte *data, int dataLen)
 {
     if (dataLen > 0)
     {
         Libsodium.crypto_generichash_blake2b_update(
             aligned,
             data,
             (ulong)dataLen
             );
     }
 }
示例#11
0
        public void GetHashAndReset(Span <byte> hash)
        {
            Debug.Assert(hash.Length == HashLen);

            Libsodium.crypto_hash_sha512_final(
                state,
                ref MemoryMarshal.GetReference(hash)
                );

            Reset();
        }
示例#12
0
 public void AppendData(ReadOnlySpan <byte> data)
 {
     if (!data.IsEmpty)
     {
         Libsodium.crypto_hash_sha512_update(
             state,
             ref MemoryMarshal.GetReference(data),
             (ulong)data.Length
             );
     }
 }
示例#13
0
        public unsafe void GetHashAndReset(byte *hash, int hashLen)
        {
            Debug.Assert(hashLen == HashLen);

            Libsodium.crypto_hash_sha256_final(
                state,
                hash
                );

            Reset();
        }
示例#14
0
        /// <inheritdoc />
        public void Dispose()
        {
            if (Interlocked.CompareExchange(ref _disposed, 1, 0) != 0)
            {
                return;
            }

            unsafe
            {
                Libsodium.sodium_free(ptr);
            }
        }
示例#15
0
        public void Dh(KeyPair keyPair, ReadOnlySpan <byte> publicKey, Span <byte> sharedKey)
        {
            Debug.Assert(keyPair.PrivateKey != null && keyPair.PrivateKey.Length == DhLen);
            Debug.Assert(publicKey.Length == DhLen);
            Debug.Assert(sharedKey.Length == DhLen);

            Libsodium.crypto_scalarmult_curve25519(
                ref MemoryMarshal.GetReference(sharedKey),
                ref MemoryMarshal.GetReference(keyPair.PrivateKey.AsSpan()),
                ref MemoryMarshal.GetReference(publicKey)
                );
        }
示例#16
0
        public unsafe void GetHashAndReset(byte *hash, int hashLen)
        {
            Debug.Assert(hashLen == HashLen);

            Libsodium.crypto_generichash_blake2b_final(
                aligned,
                hash,
                (UIntPtr)hashLen
                );

            Reset();
        }
示例#17
0
        public void GetHashAndReset(Span <byte> hash)
        {
            Debug.Assert(hash.Length == HashLen);

            Libsodium.crypto_generichash_blake2b_final(
                aligned,
                ref MemoryMarshal.GetReference(hash),
                (UIntPtr)hash.Length
                );

            Reset();
        }
示例#18
0
        public unsafe void Dh(KeyPair keyPair, ReadOnlySpan <byte> publicKey, byte *sharedKey, int sharedKeyLen)
        {
            Debug.Assert(publicKey.Length == DhLen);
            Debug.Assert(sharedKeyLen == DhLen);

            Debug.Assert(keyPair.PrivateKey != null);

            Libsodium.crypto_scalarmult_curve25519(
                sharedKey,
                keyPair.PrivateKey,
                ref MemoryMarshal.GetReference(publicKey)
                );
        }
示例#19
0
 /// <summary>
 /// Creates a new pre-shared key reference based on an existing data buffer.
 /// Mainly useful for tests, as passing an in-memory buffer exposes the key.
 /// </summary>
 /// <param name="buffer">The pre-defined buffer representing the key.</param>
 /// <returns></returns>
 public static PskRef Create(byte[] buffer)
 {
     unsafe
     {
         var len = buffer.Length;
         var b   = (byte *)Libsodium.sodium_malloc((ulong)len);
         for (var i = 0; i < buffer.Length; i++)
         {
             b[i] = buffer[i];
         }
         return(new PskRef(b, (uint)len));
     }
 }
示例#20
0
        public KeyPair GenerateKeyPair()
        {
            unsafe
            {
                var privateKey = (byte *)Libsodium.sodium_malloc((ulong)DhLen);
                try
                {
                    Libsodium.randombytes_buf(privateKey, (uint)DhLen);

                    var publicKey = new byte[DhLen];

                    Libsodium.crypto_scalarmult_curve25519_base(publicKey, privateKey);

                    return(new KeyPair(privateKey, DhLen, publicKey));
                }
                finally
                {
                    Libsodium.sodium_free(privateKey);
                }
            }
        }
示例#21
0
        public unsafe KeyPair GenerateKeyPair(byte *privateKey)
        {
            var privateKeyCopy = (byte *)Libsodium.sodium_malloc((ulong)DhLen);

            try
            {
                for (var i = 0; i < DhLen; i++)
                {
                    privateKeyCopy[i] = privateKey[i];
                }

                var publicKey = new byte[DhLen];

                Libsodium.crypto_scalarmult_curve25519_base(publicKey, privateKeyCopy);

                return(new KeyPair(privateKeyCopy, DhLen, publicKey));
            }
            finally
            {
                Libsodium.sodium_free(privateKeyCopy);
            }
        }
示例#22
0
 private void Reset()
 {
     Libsodium.crypto_generichash_blake2b_init(aligned, null, UIntPtr.Zero, (UIntPtr)HashLen);
 }
示例#23
0
 private void Reset()
 {
     Libsodium.crypto_hash_sha512_init(state);
 }