예제 #1
0
        public static unsafe bool Ecdh(byte[] agreement, byte[] publicKey, byte[] privateKey)
        {
            int outputLength = agreement.Length;

            // TODO: should probably do that only once
            secp256k1_ecdh_hash_function hashFunctionPtr = (void *output, void *x, void *y, IntPtr d) =>
            {
                Span <byte> outputSpan = new Span <byte>(output, outputLength);
                Span <byte> xSpan      = new Span <byte>(x, 32);
                if (xSpan.Length < 32)
                {
                    return(0);
                }

                xSpan.CopyTo(outputSpan);
                return(1);
            };

            GCHandle gch = GCHandle.Alloc(hashFunctionPtr);

            try
            {
                IntPtr fp = Marshal.GetFunctionPointerForDelegate(hashFunctionPtr);
                {
                    return(secp256k1_ecdh(Context, agreement, publicKey, privateKey, fp, IntPtr.Zero));
                }
            }
            finally
            {
                gch.Free();
            }
        }
예제 #2
0
        public static unsafe bool Ecdh(byte[] agreement, byte[] publicKey, byte[] privateKey)
        {
            int outputLength = agreement.Length;

            secp256k1_ecdh_hash_function hashFunctionPtr = (void *output, void *x, void *y, IntPtr d) =>
            {
                var outputSpan = new Span <byte>(output, outputLength);
                var xSpan      = new Span <byte>(x, 32);
                if (xSpan.Length < 32)
                {
                    return(0);
                }

                xSpan.CopyTo(outputSpan);
                return(1);
            };

            GCHandle gch = GCHandle.Alloc(hashFunctionPtr);

            try
            {
                IntPtr fp = Marshal.GetFunctionPointerForDelegate(hashFunctionPtr);
                {
                    return(Platform == OsPlatform.Windows
                        ? Win64Lib.secp256k1_ecdh(Context, agreement, publicKey, privateKey, fp, IntPtr.Zero)
                        : Platform == OsPlatform.Linux
                            ? PosixLib.secp256k1_ecdh(Context, agreement, publicKey, privateKey, fp, IntPtr.Zero)
                            : MacLib.secp256k1_ecdh(Context, agreement, publicKey, privateKey, fp, IntPtr.Zero));
                }
            }
            finally
            {
                gch.Free();
            }
        }
예제 #3
0
        /// <summary>
        /// Compute an EC Diffie-Hellman secret in constant time.
        /// </summary>
        /// <param name="resultOutput">A 32-byte array which will be populated by an ECDH secret computed from the point and scalar.</param>
        /// <param name="publicKey">A secp256k1_pubkey containing an initialized public key.</param>
        /// <param name="privateKey">A 32-byte scalar with which to multiply the point.</param>
        /// <param name="hashFunction">Pointer to a hash function. If null, sha256 is used.</param>
        /// <param name="data">Arbitrary data that is passed through.</param>
        /// <returns>True if exponentiation was successful, false if scalar was invalid (zero or overflow).</returns>
        public bool Ecdh(Span <byte> resultOutput, Span <byte> publicKey, Span <byte> privateKey, EcdhHashFunction hashFunction, IntPtr data)
        {
            if (resultOutput.Length < SECRET_LENGTH)
            {
                throw new ArgumentException($"{nameof(resultOutput)} must be {SECRET_LENGTH} bytes");
            }
            if (publicKey.Length < PUBKEY_LENGTH)
            {
                throw new ArgumentException($"{nameof(publicKey)} must be {PUBKEY_LENGTH} bytes");
            }
            if (privateKey.Length < PRIVKEY_LENGTH)
            {
                throw new ArgumentException($"{nameof(privateKey)} must be {PRIVKEY_LENGTH} bytes");
            }

            int outputLength = resultOutput.Length;

            secp256k1_ecdh_hash_function hashFunctionPtr = (void *output, void *x, void *y, IntPtr d) =>
            {
                var outputSpan = new Span <byte>(output, outputLength);
                var xSpan      = new Span <byte>(x, 32);
                var ySpan      = new Span <byte>(y, 32);
                return(hashFunction(outputSpan, xSpan, ySpan, d));
            };

            GCHandle gch = GCHandle.Alloc(hashFunctionPtr);

            try
            {
                var fp = Marshal.GetFunctionPointerForDelegate(hashFunctionPtr);
                fixed(byte *resPtr = &MemoryMarshal.GetReference(resultOutput),
                      pubPtr       = &MemoryMarshal.GetReference(publicKey),
                      privPtr      = &MemoryMarshal.GetReference(privateKey))
                {
                    return(secp256k1_ecdh.Value(_ctx, resPtr, pubPtr, privPtr, fp, data) == 1);
                }
            }
            finally
            {
                gch.Free();
            }
        }