This is the C# implementation of the Sessionless protocol--a protocol for providing auth without user data like emails, passwords, or sessions.
dotnet add package SessionlessNET
- Main implementations
using SessionlessNET.Impl.Sessionless;
using SessionlessNET.Impl.Vault;
- Interfaces
using SessionlessNET.Models.ISessionless;
using SessionlessNET.Models.IVault;
Almost all classes / members have xaml documentation attached to them in source. This means your IDE will show you the documentation while hovering/viewing/etc...
(Check out the complete class diagrams below)
public IVault Vault { get; }
- The way to store and retrieve
KeyPairHex
s
public string GenerateUUID();
- Creates a unique UUID for a user.
public KeyPairHex GenerateKeys();
- Generates a private/public
KeyPairHex
and stores it usingVault
- Returns:
KeyPairHex
that was generated
public Task<KeyPairHex> GenerateKeysAsync();
- Generates a private/public
KeyPairHex
asynchronously and stores it usingVault
- Returns:
KeyPairHex
that was generated
public KeyPairHex? GetKeys();
- Retrieves keys using
Vault
- Returns: Key pair as
KeyPairHex
public MessageSignatureHex Sign(string message);
- Signs a message with the user's stored private key (Get from
Vault
usingGetKeys
)- Parameters:
message
The message to be signed- Returns: Signature as a
MessageSignatureHex
public MessageSignatureHex Sign(string message, string privateKeyHex);
- Signs a message using the provided
privateKeyHex
- Parameters:
message
The message to be signedprivateKeyHex
The private key in hex format to use for signing- Returns: Signature as a
MessageSignatureHex
public MessageSignatureHex Sign(string message, ECPrivateKeyParameters privateKey);
- Signs a message using the provided
privateKey
- Parameters:
message
The message to be signedprivateKey
The private key to use for signing- Returns: Signature as a
MessageSignatureHex
public bool VerifySignature(SignedMessage signedMessage);
- Verifies a given signed message with the user's stored public key
- Parameters:
signedMessage
The message that was signed earlier- Returns: True if the signature is valid for the given message and public key
public bool VerifySignature(SignedMessageWithKey signedMessage);
- Verifies a given signed message with the included
SignedMessageWithKey.PublicKey
- Parameters:
signedMessage
The message that was signed earlier- Returns: True if the signature is valid for the given message and public key
public bool VerifySignature(SignedMessageWithECKey signedMessage);
- Verifies a given signed message with the included
SignedMessageWithECKey.PublicKey
- Parameters:
signedMessage
The message that was signed earlier- Returns: True if the signature is valid for the given message and public key
public bool Associate(params SignedMessage[] messages);
- Verifies each of the
messages
- Parameters:
...messages
Messages to be verified- Returns: True if all signatures were verified successfully
- Throws:
ArgumentException
if the messages count is <2
For more on associating keys check out this section of the dev README.
Check out the docs in the repo
classDiagram
class ISessionless {
+Vault: IVault
+GenerateUUID(): string
+GenerateKeys(): KeyPairHex
+GenerateKeysAsync(): Task<`KeyPairHex>
+GetKeys(): KeypairHex?
+Sign(string): MessageSignatureHex
+Sign(string, string): MessageSignatureHex
+Sign(string, ECPrivateKeyParameters): MessageSignatureHex
+VerifySignature(SignedMessage): bool
+VerifySignature(SignedMessageWithKey): bool
+VerifySignature(SignedMessageWithECKey): bool
+Associate(SignedMessages[]): bool
}
class Sessionless {
constructor(IVault)
}
ISessionless <-- Sessionless
classDiagram
class IVault {
+Get(): KeyPairHex?
+Save(KeyPairHex)
}
class Vault {
constructor(Func<`KeyPairHex?>, Action<`KeyPairHex>)
}
IVault <-- Vault
classDiagram
class IMessageSignature { }
class MessageSignatureInt {
+R: BigInteger
+S: BigInteger
+constructor(BigInteger, BigInteger)
+constructor(BigInteger[])
+constructor(MessageSignatureHex)
+toHex(): MessageSignatureHex
+op_explicit(MessageSignatureInt): MessageSignatureHex
}
class MessageSignatureHex {
+RHex: string
+SHex: string
+constructor(string, string)
+constructor(MessageSignatureInt)
+toInt(): MessageSignatureInt
+op_explicit(MessageSignatureHex): MessageSignatureInt
}
IMessageSignature <-- MessageSignatureInt
IMessageSignature <-- MessageSignatureHex
classDiagram
class SignedMessage {
+Message: string
+Signature: MessageSignatureHex
+constructor(string, MessageSignatureHex)
+WithKey(string): SignedMessageWithKey
+WithKey(ECPublicKeyParameters): SignedMessageWithECKey
}
class SignedMessageWithKey {
+PublicKey: string
+constructor(string, MessageSignatureHex, string)
+constructor(SignedMessage, string)
}
class SignedMessageWithECKey {
+PublicKey: ECPublicKeyParameters
+constructor(string, MessageSignatureHex, ECPublicKeyParameters)
+constructor(SignedMessage, ECPublicKeyParameters)
}
SignedMessage <-- SignedMessageWithKey
SignedMessage <-- SignedMessageWithECKey
classDiagram
class KeyPairHex {
+PrivateKey: string
+PublicKey: string
+constructor(string, string)
}
classDiagram
class KeyPairNotFoundException {
constructor()
}
class HexFormatRequiredException {
constructor(string)
}
Exception <-- KeyPairNotFoundException
Exception <.. FormatException
FormatException <-- HexFormatRequiredException