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); } }
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); } }
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); } }
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); }
/// <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); } }
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(); } }
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); }
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()); } }
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.") });
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"); } }
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"); } }
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"); } }
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."); }
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."); }
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."); }
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."); }
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); }
/// <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); } }