Beispiel #1
0
        public static unsafe void HashWithDomain(out Span <byte> signatureBytes, out Span <byte> blsSignatureBytes, Span <byte> hashBytes, Span <byte> domainBytes)
        {
            blsSignatureBytes = new byte[BlsSignatureLength];
            signatureBytes    = new byte[SignatureLength];

            Span <byte> hashWithDomain = stackalloc byte[HashLength + DomainLength];

            hashBytes.CopyTo(hashWithDomain.Slice(0, 32));
            domainBytes.CopyTo(hashWithDomain.Slice(32, 8));

            fixed(byte *signatureBytesRef = signatureBytes)
            fixed(byte *blsSignatureBytesRef = blsSignatureBytes)
            fixed(byte *hashWithDomainRef    = hashWithDomain)
            {
                switch (Platform)
                {
                case OsPlatform.Windows:
                    Win64Lib.blsHashWithDomainToFp2(signatureBytesRef, hashWithDomainRef);
                    break;

                case OsPlatform.Mac:
                    MacLib.blsHashWithDomainToFp2(signatureBytesRef, hashWithDomainRef);
                    break;

                case OsPlatform.Linux:
                    PosixLib.blsHashWithDomainToFp2(signatureBytesRef, hashWithDomainRef);
                    break;

                default:
                    throw new ArgumentOutOfRangeException(Platform.ToString());
                }

                DeserializeSignature(blsSignatureBytesRef, signatureBytesRef);
            }
        }
Beispiel #2
0
        public static unsafe void AddSignature(Span <byte> a, Span <byte> b)
        {
            Span <byte> blsA = stackalloc byte[BlsSignatureLength];
            Span <byte> blsB = stackalloc byte[BlsSignatureLength];

            fixed(byte *aRef = a)
            fixed(byte *bRef    = b)
            fixed(byte *blsARef = blsA)
            fixed(byte *blsBRef = blsB)
            {
                DeserializeSignature(blsARef, aRef);
                DeserializeSignature(blsBRef, bRef);

                switch (Platform)
                {
                case OsPlatform.Windows:
                    Win64Lib.blsSignatureAdd(blsARef, blsBRef);
                    break;

                case OsPlatform.Mac:
                    MacLib.blsSignatureAdd(blsARef, blsBRef);
                    break;

                case OsPlatform.Linux:
                    PosixLib.blsSignatureAdd(blsARef, blsBRef);
                    break;

                default:
                    throw new ArgumentOutOfRangeException(Platform.ToString());
                }

                SerializeSignature(aRef, blsARef);
            }
        }
Beispiel #3
0
        public static unsafe void GetPublicKey(Span <byte> privateKeyBytes, out Span <byte> publicKeyBytes)
        {
            Span <byte> blsPrivateKey = stackalloc byte[BlsPrivateKeyLength];
            Span <byte> blsPublicKey  = stackalloc byte[BlsPublicKeyLength];

            publicKeyBytes = new byte[PublicKeyLength];

            fixed(byte *privateKeyBytesRef = privateKeyBytes)
            fixed(byte *publicKeyBytesRef = publicKeyBytes)
            fixed(byte *blsPrivateKeyRef  = blsPrivateKey)
            fixed(byte *blsPublicKeyRef   = blsPublicKey)
            {
                DeserializePrivateKey(blsPrivateKeyRef, privateKeyBytesRef);

                switch (Platform)
                {
                case OsPlatform.Windows:
                    Win64Lib.blsGetPublicKey(blsPublicKeyRef, blsPrivateKeyRef);
                    break;

                case OsPlatform.Mac:
                    MacLib.blsGetPublicKey(blsPublicKeyRef, blsPrivateKeyRef);
                    break;

                case OsPlatform.Linux:
                    PosixLib.blsGetPublicKey(blsPublicKeyRef, blsPrivateKeyRef);
                    break;

                default:
                    throw new ArgumentOutOfRangeException(Platform.ToString());
                }

                SerializePublicKey(publicKeyBytesRef, blsPublicKeyRef);
            }
        }
Beispiel #4
0
        public static byte[] GetPublicKey(byte[] privateKey, bool compressed)
        {
            byte[] publicKey = new byte[64];
            if (Platform == OsPlatform.Windows
                ? !Win64Lib.secp256k1_ec_pubkey_create(Context, publicKey, privateKey)
                : !(Platform == OsPlatform.Linux
                    ? PosixLib.secp256k1_ec_pubkey_create(Context, publicKey, privateKey)
                    : MacLib.secp256k1_ec_pubkey_create(Context, publicKey, privateKey)))
            {
                return(null);
            }

            byte[] serializedPublicKey = new byte[compressed ? 33 : 65];
            uint   outputSize          = (uint)serializedPublicKey.Length;
            uint   flags = compressed ? Secp256K1EcCompressed : Secp256K1EcUncompressed;

            if (Platform == OsPlatform.Windows
                ? !Win64Lib.secp256k1_ec_pubkey_serialize(Context, serializedPublicKey, ref outputSize, publicKey, flags)
                : !(Platform == OsPlatform.Linux
                    ? PosixLib.secp256k1_ec_pubkey_serialize(Context, serializedPublicKey, ref outputSize, publicKey, flags)
                    : MacLib.secp256k1_ec_pubkey_serialize(Context, serializedPublicKey, ref outputSize, publicKey, flags)))
            {
                return(null);
            }

            return(serializedPublicKey);
        }
Beispiel #5
0
        /// <summary>
        /// Serialize a pubkey object into a serialized byte sequence.
        /// </summary>
        /// <param name="serializedPublicKeyOutput">65-byte (if compressed==0) or 33-byte (if compressed==1) output to place the serialized key in.</param>
        /// <param name="publicKey">The secp256k1_pubkey initialized public key.</param>
        /// <param name="flags">SECP256K1_EC_COMPRESSED if serialization should be in compressed format, otherwise SECP256K1_EC_UNCOMPRESSED.</param>
        public static unsafe bool PublicKeySerialize(Span <byte> serializedPublicKeyOutput, Span <byte> publicKey, uint flags = Secp256K1EcUncompressed)
        {
            bool compressed             = (flags & Secp256K1EcCompressed) == Secp256K1EcCompressed;
            int  serializedPubKeyLength = compressed ? 33 : 65;

            if (serializedPublicKeyOutput.Length < serializedPubKeyLength)
            {
                string compressedStr = compressed ? "compressed" : "uncompressed";
                throw new ArgumentException($"{nameof(serializedPublicKeyOutput)} ({compressedStr}) must be {serializedPubKeyLength} bytes");
            }
            if (publicKey.Length < 64)
            {
                throw new ArgumentException($"{nameof(publicKey)} must be {64} bytes");
            }

            uint newLength = (uint)serializedPubKeyLength;

            fixed(byte *serializedPtr = &MemoryMarshal.GetReference(serializedPublicKeyOutput),
                  pubKeyPtr           = &MemoryMarshal.GetReference(publicKey))
            {
                var result = (Platform == OsPlatform.Windows
                           ? Win64Lib.secp256k1_ec_pubkey_serialize(Context, serializedPtr, ref newLength, pubKeyPtr, (uint)flags)
                           : Platform == OsPlatform.Linux
                               ? PosixLib.secp256k1_ec_pubkey_serialize(Context, serializedPtr, ref newLength, pubKeyPtr, (uint)flags)
                               : MacLib.secp256k1_ec_pubkey_serialize(Context, serializedPtr, ref newLength, pubKeyPtr, (uint)flags));

                return(result == 1 && newLength == serializedPubKeyLength);
            }
        }
Beispiel #6
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();
            }
        }
Beispiel #7
0
        public static byte[] SignCompact(byte[] messageHash, byte[] privateKey, out int recoveryId)
        {
            byte[] recoverableSignature = new byte[65];
            recoveryId = 0;

            if (Platform == OsPlatform.Windows
                ? !Win64Lib.secp256k1_ecdsa_sign_recoverable(Context, recoverableSignature, messageHash, privateKey, IntPtr.Zero, IntPtr.Zero)
                : !(Platform == OsPlatform.Linux
                    ? PosixLib.secp256k1_ecdsa_sign_recoverable(Context, recoverableSignature, messageHash, privateKey, IntPtr.Zero, IntPtr.Zero)
                    : MacLib.secp256k1_ecdsa_sign_recoverable(Context, recoverableSignature, messageHash, privateKey, IntPtr.Zero, IntPtr.Zero)))
            {
                return(null);
            }

            byte[] compactSignature = new byte[64];
            if (Platform == OsPlatform.Windows
                ? !Win64Lib.secp256k1_ecdsa_recoverable_signature_serialize_compact(Context, compactSignature, out recoveryId, recoverableSignature)
                : !(Platform == OsPlatform.Linux
                    ? PosixLib.secp256k1_ecdsa_recoverable_signature_serialize_compact(Context, compactSignature, out recoveryId, recoverableSignature)
                    : MacLib.secp256k1_ecdsa_recoverable_signature_serialize_compact(Context, compactSignature, out recoveryId, recoverableSignature)))
            {
                return(null);
            }

            return(compactSignature);
        }
Beispiel #8
0
        static BlsProxy()
        {
            Platform = GetPlatform();

            int initResult = Platform switch
            {
                OsPlatform.Windows => Win64Lib.blsInit(MclBls12_381CurveId, MclBnCompileTimeVar),
                OsPlatform.Linux => PosixLib.blsInit(MclBls12_381CurveId, MclBnCompileTimeVar),
                OsPlatform.Mac => MacLib.blsInit(MclBls12_381CurveId, MclBnCompileTimeVar),
                _ => throw new ArgumentOutOfRangeException(Platform.ToString())
            };

            if (initResult != 0)
            {
                throw new CryptographicException($"Unable to load the BLS lib: {initResult}");
            }

            switch (Platform)
            {
            case OsPlatform.Windows:
                Win64Lib.blsSetETHserialization(1);
                break;

            case OsPlatform.Mac:
                MacLib.blsSetETHserialization(1);
                break;

            case OsPlatform.Linux:
                PosixLib.blsSetETHserialization(1);
                break;

            default:
                throw new ArgumentOutOfRangeException(Platform.ToString());
            }
        }
Beispiel #9
0
 private static IntPtr CreateContext()
 {
     return(Platform switch
     {
         OsPlatform.Windows => Win64Lib.secp256k1_context_create(Secp256K1ContextSign | Secp256K1ContextVerify),
         OsPlatform.Linux => PosixLib.secp256k1_context_create(Secp256K1ContextSign | Secp256K1ContextVerify),
         OsPlatform.Mac => MacLib.secp256k1_context_create(Secp256K1ContextSign | Secp256K1ContextVerify),
         _ => throw new InvalidOperationException("Unsupported platform.")
     });
Beispiel #10
0
        private static unsafe void SerializePublicKey(byte *serializedRef, byte *deserializedRef)
        {
            int bytesWritten = Platform switch
            {
                OsPlatform.Windows => Win64Lib.blsPublicKeySerialize(serializedRef, PublicKeyLength, deserializedRef),
                OsPlatform.Linux => PosixLib.blsPublicKeySerialize(serializedRef, PublicKeyLength, deserializedRef),
                OsPlatform.Mac => MacLib.blsPublicKeySerialize(serializedRef, PublicKeyLength, deserializedRef),
                _ => throw new ArgumentOutOfRangeException(Platform.ToString())
            };

            if (bytesWritten != PublicKeyLength)
            {
                throw new CryptographicException($"Bytes written was {bytesWritten} when serializing public key");
            }
        }
Beispiel #11
0
        private static unsafe void DeserializePrivateKey(byte *deserializedRef, byte *serializedRef)
        {
            int bytesRead = Platform switch
            {
                OsPlatform.Windows => Win64Lib.blsSecretKeyDeserialize(deserializedRef, serializedRef, PrivateKeyLength),
                OsPlatform.Linux => PosixLib.blsSecretKeyDeserialize(deserializedRef, serializedRef, PrivateKeyLength),
                OsPlatform.Mac => MacLib.blsSecretKeyDeserialize(deserializedRef, serializedRef, PrivateKeyLength),
                _ => throw new ArgumentOutOfRangeException(Platform.ToString())
            };

            if (bytesRead != PrivateKeyLength)
            {
                throw new CryptographicException($"Bytes read was {bytesRead} instead of {PrivateKeyLength} when deserializing private key");
            }
        }
Beispiel #12
0
        private static unsafe void SerializeSignature(byte *serializedRef, byte *deserializedRef)
        {
            int bytesWritten = Platform switch
            {
                OsPlatform.Windows => Win64Lib.blsSignatureSerialize(serializedRef, SignatureLength, deserializedRef),
                OsPlatform.Linux => PosixLib.blsSignatureSerialize(serializedRef, SignatureLength, deserializedRef),
                OsPlatform.Mac => MacLib.blsSignatureSerialize(serializedRef, SignatureLength, deserializedRef),
                _ => throw new ArgumentOutOfRangeException(Platform.ToString())
            };

            if (bytesWritten != SignatureLength)
            {
                throw new CryptographicException($"Bytes written was {bytesWritten} instead of {SignatureLength} when deserializing private key");
            }
        }
Beispiel #13
0
        public static bool VerifyPrivateKey(byte[] privateKey)
        {
            switch (Platform)
            {
            case OsPlatform.Windows:
                return(Win64Lib.secp256k1_ec_seckey_verify(Context, privateKey));

            case OsPlatform.Linux:
                return(PosixLib.secp256k1_ec_seckey_verify(Context, privateKey));

            case OsPlatform.Mac:
                return(MacLib.secp256k1_ec_seckey_verify(Context, privateKey));
            }

            throw new InvalidOperationException("Unsupported platform.");
        }
Beispiel #14
0
        private static IntPtr CreateContext()
        {
            switch (Platform)
            {
            case OsPlatform.Windows:
                return(Win64Lib.secp256k1_context_create(Secp256K1ContextSign | Secp256K1ContextVerify));

            case OsPlatform.Linux:
                return(PosixLib.secp256k1_context_create(Secp256K1ContextSign | Secp256K1ContextVerify));

            case OsPlatform.Mac:
                return(MacLib.secp256k1_context_create(Secp256K1ContextSign | Secp256K1ContextVerify));
            }

            throw new InvalidOperationException("Unsupported platform.");
        }
Beispiel #15
0
        public static string GetSolcVersion()
        {
            switch (Platform)
            {
            case OsPlatform.Windows:
                return(Win64Lib.version());

            case OsPlatform.Linux:
                return(PosixLib.version());

            case OsPlatform.Mac:
                return(MacLib.version());
            }

            throw new InvalidOperationException("Unsupported platform.");
        }
Beispiel #16
0
        public static string Compile(string contract, string evmVersion, bool optimize, uint?runs)
        {
            string input = new CompilerInput(contract, evmVersion, optimize, runs).Value();

            switch (Platform)
            {
            case OsPlatform.Windows:
                return(Win64Lib.compileStandard(input, null));

            case OsPlatform.Linux:
                return(PosixLib.compileStandard(input, null));

            case OsPlatform.Mac:
                return(MacLib.compileStandard(input, null));
            }

            throw new InvalidOperationException("Unsupported platform.");
        }
Beispiel #17
0
        public static byte[] RecoverKeyFromCompact(byte[] messageHash, byte[] compactSignature, int recoveryId, bool compressed)
        {
            byte[] recoverableSignature = new byte[65];

            if (Platform == OsPlatform.Windows
                ? !Win64Lib.secp256k1_ecdsa_recoverable_signature_parse_compact(Context, recoverableSignature, compactSignature, recoveryId)
                : !(Platform == OsPlatform.Linux
                    ? PosixLib.secp256k1_ecdsa_recoverable_signature_parse_compact(Context, recoverableSignature, compactSignature, recoveryId)
                    : MacLib.secp256k1_ecdsa_recoverable_signature_parse_compact(Context, recoverableSignature, compactSignature, recoveryId)))
            {
                return(null);
            }

            byte[] publicKey = new byte[64];
            if (Platform == OsPlatform.Windows
                ? !Win64Lib.secp256k1_ecdsa_recover(Context, publicKey, recoverableSignature, messageHash)
                : !(Platform == OsPlatform.Linux
                    ? PosixLib.secp256k1_ecdsa_recover(Context, publicKey, recoverableSignature, messageHash)
                    : MacLib.secp256k1_ecdsa_recover(Context, publicKey, recoverableSignature, messageHash)))
            {
                return(null);
            }

            uint flags = compressed ? Secp256K1EcCompressed : Secp256K1EcUncompressed;

            byte[] serializedPublicKey = new byte[compressed ? 33 : 65];
            uint   outputSize          = (uint)serializedPublicKey.Length;

            if (Platform == OsPlatform.Windows
                ? !Win64Lib.secp256k1_ec_pubkey_serialize(Context, serializedPublicKey, ref outputSize, publicKey, flags)
                : !(Platform == OsPlatform.Linux
                    ? PosixLib.secp256k1_ec_pubkey_serialize(Context, serializedPublicKey, ref outputSize, publicKey, flags)
                    : MacLib.secp256k1_ec_pubkey_serialize(Context, serializedPublicKey, ref outputSize, publicKey, flags)))
            {
                return(null);
            }

            return(serializedPublicKey);
        }
Beispiel #18
0
        /// <summary>
        /// Parse a variable-length public key into the pubkey object.
        /// This function supports parsing compressed (33 bytes, header byte 0x02 or
        /// 0x03), uncompressed(65 bytes, header byte 0x04), or hybrid(65 bytes, header
        /// byte 0x06 or 0x07) format public keys.
        /// </summary>
        /// <param name="publicKeyOutput">(Output) pointer to a pubkey object. If 1 is returned, it is set to a parsed version of input. If not, its value is undefined.</param>
        /// <param name="serializedPublicKey">Serialized public key.</param>
        /// <returns>True if the public key was fully valid, false if the public key could not be parsed or is invalid.</returns>
        public static unsafe bool PublicKeyParse(Span <byte> publicKeyOutput, Span <byte> serializedPublicKey)
        {
            var inputLen = serializedPublicKey.Length;

            if (inputLen != 33 && inputLen != 65)
            {
                throw new ArgumentException($"{nameof(serializedPublicKey)} must be 33 or 65 bytes");
            }

            if (publicKeyOutput.Length < 64)
            {
                throw new ArgumentException($"{nameof(publicKeyOutput)} must be {64} bytes");
            }

            fixed(byte *pubKeyPtr = &MemoryMarshal.GetReference(publicKeyOutput),
                  serializedPtr   = &MemoryMarshal.GetReference(serializedPublicKey))
            {
                return((Platform == OsPlatform.Windows
                    ? Win64Lib.secp256k1_ec_pubkey_parse(Context, pubKeyPtr, serializedPtr, (uint)inputLen)
                    : Platform == OsPlatform.Linux
                        ? PosixLib.secp256k1_ec_pubkey_parse(Context, pubKeyPtr, serializedPtr, (uint)inputLen)
                        : MacLib.secp256k1_ec_pubkey_parse(Context, pubKeyPtr, serializedPtr, (uint)inputLen)) == 1);
            }
        }