diff --git a/src/client.nim b/src/client.nim index a4c2ee8..ab5e93c 100644 --- a/src/client.nim +++ b/src/client.nim @@ -14,7 +14,7 @@ import chronicles type KeyEntry* = object keytype: string - keypair: SkKeyPair + privateKey: PrivateKey timestamp: int64 @@ -87,16 +87,16 @@ proc createIntroBundle*(self: var Client): IntroBundle = ## the required information to send a message. # Create Ephemeral keypair, save it in the key store - let ephemeral_keypair = generate_keypair() - self.key_store[ephemeral_keypair.pubkey.toHexCompressed()] = KeyEntry( + let ephemeral_key = generate_key() + self.key_store[ephemeral_key.getPublickey().bytes().bytesToHex()] = KeyEntry( keytype: "ephemeral", - keypair: ephemeral_keypair, + privateKEy: ephemeral_key, timestamp: getTime().toUnix(), ) result = IntroBundle( - ident: @(self.ident.getPubkey().toRawCompressed()), - ephemeral: @(ephemeral_keypair.pubkey.toRawCompressed()), + ident: @(self.ident.getPubkey().bytes()), + ephemeral: @(ephemeral_key.getPublicKey().bytes()), ) proc createPrivateConversation*(self: var Client, participant: PublicKey, @@ -114,7 +114,7 @@ proc createPrivateConversation*(self: var Client, participant: PublicKey, proc handleIntro*(self: var Client, intro_bundle: IntroBundle): TransportMessage = ## Creates a private conversation with the given Invitebundle. - let res_pubkey = SkPublicKey.fromRaw(intro_bundle.ident) + let res_pubkey = loadPublicKeyFromBytes(intro_bundle.ident) if res_pubkey.isErr: raise newException(ValueError, "Invalid public key in intro bundle.") let dest_pubkey = res_pubkey.get() @@ -123,9 +123,9 @@ proc handleIntro*(self: var Client, intro_bundle: IntroBundle): TransportMessage let dst_convo_topic = topic_inbox(dest_pubkey.get_addr()) let invite = InvitePrivateV1( - initiator: @(self.ident.getPubkey().toRawCompressed()), + initiator: @(self.ident.getPubkey().bytes()), initiator_ephemeral: @[0, 0], # TODO: Add ephemeral - participant: @(dest_pubkey.toRawCompressed()), + participant: @(dest_pubkey.bytes()), participant_ephemeral_id: intro_bundle.ephemeral_id, discriminator: "test" ) @@ -176,7 +176,7 @@ proc recv*(self: var Client, transport_message: TransportMessage): seq[ proc processInvite*(self: var Client, invite: InvitePrivateV1) = debug "Callback Invoked", invite = invite - createPrivateConversation(self, PublicKey.fromRaw( + createPrivateConversation(self, loadPublicKeyFromBytes( invite.initiator).get(), invite.discriminator) diff --git a/src/crypto.nim b/src/crypto.nim index d4de268..6853e53 100644 --- a/src/crypto.nim +++ b/src/crypto.nim @@ -1,12 +1,11 @@ import proto_types -import secp256k1 +import crypto/ecdh import std/[sysrand] -export secp256k1 +import results - -type KeyPair* = SkKeyPair -type PublicKey* = SkPublicKey +export PublicKey, PrivateKey, bytes, createRandomKey, loadPrivateKeyFromBytes, loadPublicKeyFromBytes, + getPublicKey, Dh, Result proc encrypt_plain*[T: EncryptableTypes](frame: T): EncryptedPayload = @@ -23,11 +22,6 @@ proc decrypt_plain*[T: EncryptableTypes](ciphertext: Plaintext, t: typedesc[ result = ok(obj.get()) -proc generate_keypair*(): KeyPair = - var rng: Rng = urandom - let res = SkKeyPair.random(rng) - if res.isErr: - raise newException(ValueError, "Failed to generate keypair: ") - - result = res.get() +proc generate_key*(): PrivateKey = + createRandomKey().get() diff --git a/src/crypto/ecdh.nim b/src/crypto/ecdh.nim index 733e91e..0512f4b 100644 --- a/src/crypto/ecdh.nim +++ b/src/crypto/ecdh.nim @@ -21,11 +21,16 @@ proc createRandomKey*(): Result[PrivateKey, string] = return err("Failed to create HmacDrbgContext with system randomness") ok(PrivateKey(bytes: Curve25519Key.random(rng[]))) -proc loadKeyFromBytes*(bytes: openArray[byte]): Result[PrivateKey, string] = +proc loadPrivateKeyFromBytes*(bytes: openArray[byte]): Result[PrivateKey, string] = if bytes.len != Curve25519KeySize: return err("Private key size must be 32 bytes") ok(PrivateKey(bytes: intoCurve25519Key(bytes))) +proc loadPublicKeyFromBytes*(bytes: openArray[byte]): Result[PublicKey, string] = + if bytes.len != Curve25519KeySize: + return err("Public key size must be 32 bytes") + ok(PublicKey(bytes: intoCurve25519Key(bytes))) + proc getPublicKey*(privateKey: PrivateKey): PublicKey = PublicKey(bytes: public(privateKey.bytes)) diff --git a/src/identity.nim b/src/identity.nim index c30d8b1..29d2df5 100644 --- a/src/identity.nim +++ b/src/identity.nim @@ -1,12 +1,13 @@ import crypto import utils +import results type Identity* = object name: string - keypair: KeyPair + privateKey: PrivateKey ################################################# @@ -14,17 +15,17 @@ type ################################################# proc createIdentity*(name: string): Identity = - let keypair = generate_keypair() - result = Identity(name: name, keypair: keypair) + let privKey = createRandomKey().get() + result = Identity(name: name, privateKey: privKey) ################################################# # Parameter Access ################################################# +proc getPubkey*(self: Identity): PublicKey = + result = self.privateKey.getPublicKey() + proc getAddr*(self: Identity): string = - result = get_addr(self.keypair.pubkey) + result = get_addr(self.getPubKey()) - -proc getPubkey*(self: Identity): SkPublicKey = - result = self.keypair.pubkey diff --git a/src/inbox.nim b/src/inbox.nim index fdf9231..48b1511 100644 --- a/src/inbox.nim +++ b/src/inbox.nim @@ -2,8 +2,8 @@ import crypto import proto_types import utils import dev - import chronicles +import results type InviteCallback* = proc(invite: InvitePrivateV1): void @@ -32,7 +32,7 @@ proc wrap_env*(payload: EncryptedPayload, convo_id: string): WapEnvelopeV1 = conversation_hint: convo_id, ) -proc conversation_id_for*(pubkey: SkPublicKey): string = +proc conversation_id_for*(pubkey: PublicKey): string = ## Generates a conversation ID based on the public key. return "/convo/inbox/v1" & pubkey.get_addr() diff --git a/src/utils.nim b/src/utils.nim index 5f3e9be..a77ece2 100644 --- a/src/utils.nim +++ b/src/utils.nim @@ -21,10 +21,14 @@ proc get_addr*(pubkey: SkPublicKey): string = # TODO: Needs Spec result = hash_func(pubkey.toHexCompressed()) +proc bytesToHex*[T](bytes: openarray[T], lowercase: bool = false): string = + ## Convert bytes to hex string with case option + result = "" + for b in bytes: + let hex = b.toHex(2) + result.add(if lowercase: hex.toLower() else: hex) + +proc get_addr*(pubkey: PublicKey): string = + # TODO: Needs Spec + result = hash_func(pubkey.bytes().bytesToHex()) -proc bytesToHex*(bytes: openarray[byte], lowercase: bool = false): string = - ## Convert bytes to hex string with case option - result = "" - for b in bytes: - let hex = b.toHex(2) - result.add(if lowercase: hex.toLower() else: hex)