Skip to content

Commit

Permalink
Bearer Did Impl (etro-js#247)
Browse files Browse the repository at this point in the history
* bearer did wip

* update

* documentation

* update

* comply to bearerdid spec
  • Loading branch information
nitro-neal authored Jun 25, 2024
1 parent 7e196fe commit 1155fed
Show file tree
Hide file tree
Showing 16 changed files with 235 additions and 114 deletions.
51 changes: 36 additions & 15 deletions bound/kt/src/main/kotlin/web5/sdk/crypto/keys/InMemoryKeyManager.kt
Original file line number Diff line number Diff line change
@@ -1,33 +1,54 @@
package web5.sdk.crypto.keys

import web5.sdk.crypto.signers.OuterSigner
import web5.sdk.crypto.signers.Signer

import web5.sdk.rust.InMemoryKeyManager as RustCoreInMemoryKeyManager
import web5.sdk.rust.KeyManager as RustCoreKeyManager

/**
* A class for managing cryptographic keys in-memory.
*/
class InMemoryKeyManager {
private val rustCoreKeyManager = RustCoreInMemoryKeyManager()
class InMemoryKeyManager : KeyManager {
private val rustCoreInMemoryKeyManager = RustCoreInMemoryKeyManager()

/**
* Constructs an InMemoryKeyManager with the given private keys.
*
* @param privateJwks A list of private keys represented as JWKs (JSON Web Keys).
*/
constructor(privateJwks: List<Jwk>) {
privateJwks.forEach {
this.rustCoreInMemoryKeyManager.importPrivateJwk(it)
}
}

/**
* Returns the Signer for the given public key.
*
* @param publicJwk The public key represented as a JWK.
* @return Signer The signer for the given public key.
*/
override fun getSigner(publicJwk: Jwk): Signer {
val innerSigner = this.rustCoreInMemoryKeyManager.getSigner(publicJwk)
return OuterSigner(innerSigner)
}

/**
* Returns the Ed25519Signer for the given public key.
* Returns the RustCoreKeyManager.
*
* @param publicKey the public key represented as a Jwk.
* @return Ed25519Signer the signer for the given public key.
* @return RustCoreKeyManager The rust core key manager.
*/
fun getSigner(publicKey: Jwk): Signer {
return rustCoreKeyManager.getSigner(publicKey)
override fun getRustCoreKeyManager(): RustCoreKeyManager {
return this.rustCoreInMemoryKeyManager.getAsKeyManager()
}

/**
* For importing private keys which may be stored somewhere such as environment variables.
* Returns Jwk which is the public key for the given private key.
* Imports a private key which may be stored somewhere such as environment variables.
*
* @param privateKey the private key represented as a Jwk.
* @return Jwk the public key for the given private key.
* @param privateJwk The private key represented as a JWK.
* @return Jwk The public key represented as a JWK.
*/
fun importPrivateKey(privateKey: Jwk): Jwk {
return rustCoreKeyManager.importPrivateJwk(privateKey)
fun importPrivateJwk(privateJwk: Jwk): Jwk {
return this.rustCoreInMemoryKeyManager.importPrivateJwk(privateJwk)
}
}
}
17 changes: 5 additions & 12 deletions bound/kt/src/main/kotlin/web5/sdk/crypto/keys/KeyManager.kt
Original file line number Diff line number Diff line change
@@ -1,32 +1,25 @@
package web5.sdk.crypto.keys

import web5.sdk.crypto.signers.Signer
import web5.sdk.rust.KeyManager as RustCoreKeyManager

/**
* An interface representing a key manager for cryptographic operations.
*/
interface KeyManager {
/**
* Generates new key material and returns the public key represented as a Jwk.
*
* @return Jwk The generated public key.
*/
fun generateKeyMaterial(): Jwk

/**
* Returns the signer for the given public key.
*
* @param publicKey The public key represented as a Jwk.
* @return Signer The signer for the given public key.
*/
fun getSigner(publicKey: Jwk): Signer
fun getSigner(publicJwk: Jwk): Signer

/**
* Imports a key which may be stored somewhere such as environment variables.
* Returns the public key for the given private key.
* Returns the RustCoreKeyManager
*
* @param privateKey The private key represented as a Jwk.
* @return Jwk The public key for the given private key.
* @return RustCoreKeyManager The rust core key manager
*/
fun importKey(privateKey: Jwk): Jwk
fun getRustCoreKeyManager(): RustCoreKeyManager
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class Ed25519Signer : Signer {
* @return ByteArray the signature.
*/
@OptIn(ExperimentalUnsignedTypes::class)
override fun sign(payload: List<UByte>): ByteArray {
override fun sign(payload: ByteArray): ByteArray {
val uByteList = payload.toUByteArray().toList()
return rustCoreSigner.sign(uByteList)
}
Expand Down
19 changes: 17 additions & 2 deletions bound/kt/src/main/kotlin/web5/sdk/crypto/signers/Signer.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
package web5.sdk.crypto.signers

import web5.sdk.rust.SignerInterface as RustCoreSignerInterface
import web5.sdk.rust.Signer as RustCoreSigner

typealias Signer = RustCoreSignerInterface
interface Signer {
fun sign(payload: ByteArray): ByteArray
}

class OuterSigner: Signer {
private val rustCoreSigner: RustCoreSigner

constructor(rustCoreSigner: RustCoreSigner) {
this.rustCoreSigner = rustCoreSigner
}

@OptIn(ExperimentalUnsignedTypes::class)
override fun sign(payload: ByteArray): ByteArray {
return this.rustCoreSigner.sign(payload.toUByteArray().toList())
}
}
47 changes: 47 additions & 0 deletions bound/kt/src/main/kotlin/web5/sdk/dids/BearerDid.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package web5.sdk.dids

import web5.sdk.crypto.signers.Signer
import web5.sdk.crypto.keys.KeyManager
import web5.sdk.crypto.signers.OuterSigner

import web5.sdk.rust.BearerDid as RustCoreBearerDid

/**
* Represents a Decentralized Identifier (DID) along with its DID document, key manager, metadata,
* and convenience functions.
*
* @property did The DID associated with this instance.
* @property document The DID document associated with this instance.
*/
class BearerDid {
val did: Did
val document: Document

private val keyManager: KeyManager
private val rustCoreBearerDid: RustCoreBearerDid

/**
* Constructs a BearerDid instance using a DID URI and a key manager.
*
* @param uri The DID URI.
* @param keyManager The key manager to handle keys.
*/
constructor(uri: String, keyManager: KeyManager) {
this.rustCoreBearerDid = RustCoreBearerDid(uri, keyManager.getRustCoreKeyManager())

this.did = this.rustCoreBearerDid.getData().did
this.document = this.rustCoreBearerDid.getData().document
this.keyManager = keyManager
}

/**
* Returns a signer for the DID.
*
* @return Signer The signer for the DID.
*/
fun getSigner(): Signer {
val keyId = this.document.verificationMethod.first().id
val innerSigner = this.rustCoreBearerDid.getSigner(keyId)
return OuterSigner(innerSigner)
}
}
59 changes: 1 addition & 58 deletions bound/kt/src/main/kotlin/web5/sdk/dids/Did.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,62 +4,5 @@ import web5.sdk.rust.DidData as RustCoreDidData

/**
* Representation of a [DID Core Identifier](https://www.w3.org/TR/did-core/#identifiers).
*
* @property uri Represents the complete Decentralized Identifier (DID) URI.
* @property url Represents the DID URI + A network location identifier for a specific resource.
* @property method Specifies the DID method in the URI, indicating the underlying method-specific identifier scheme.
* @property id The method-specific identifier in the DID URI.
* @property params A map containing optional parameters present in the DID URI. These parameters are method-specific.
* @property path An optional path component in the DID URI.
* @property query An optional query component in the DID URI, used to express a request for a specific representation or resource related to the DID.
* @property fragment An optional fragment component in the DID URI, used to reference a specific part of a DID document.
*/
data class Did(
val uri: String,
val url: String,
val method: String,
val id: String,
val params: Map<String, String> = emptyMap(),
val path: String? = null,
val query: String? = null,
val fragment: String? = null
) {
/**
* Converts the Did instance to a RustCoreDidData binding.
*
* @return RustCoreDidData the corresponding RustCoreDidData object.
*/
fun toRustCore(): RustCoreDidData {
return RustCoreDidData(
uri = this.uri,
url = this.url,
method = this.method,
id = this.id,
params = this.params.ifEmpty { null },
path = this.path,
query = this.query,
fragment = this.fragment
)
}

companion object {
/**
* Creates a Did instance from a RustCoreDidData binding.
*
* @param didData the RustCoreDidData object.
* @return Did the corresponding Did instance.
*/
fun fromRustCore(didData: RustCoreDidData): Did {
return Did(
uri = didData.uri,
url = didData.url,
method = didData.method,
id = didData.id,
params = didData.params ?: emptyMap(),
path = didData.path,
query = didData.query,
fragment = didData.fragment
)
}
}
}
typealias Did = RustCoreDidData
4 changes: 2 additions & 2 deletions bound/kt/src/main/kotlin/web5/sdk/dids/methods/dht/DidDht.kt
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class DidDht {
constructor(identityKey: Jwk) {
rustCoreDidDht = RustCoreDidDht.fromIdentityKey(identityKey)

this.did = Did.fromRustCore(rustCoreDidDht.getData().did)
this.did = rustCoreDidDht.getData().did
this.document = rustCoreDidDht.getData().document
}

Expand All @@ -42,7 +42,7 @@ class DidDht {
constructor(uri: String) {
rustCoreDidDht = RustCoreDidDht.fromUri(uri)

this.did = Did.fromRustCore(rustCoreDidDht.getData().did)
this.did = rustCoreDidDht.getData().did
this.document = rustCoreDidDht.getData().document
}

Expand Down
4 changes: 2 additions & 2 deletions bound/kt/src/main/kotlin/web5/sdk/dids/methods/jwk/DidJwk.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class DidJwk {
constructor(publicKey: Jwk) {
val rustCoreDidJwk = RustCoreDidJwk.fromPublicJwk(publicKey)

this.did = Did.fromRustCore(rustCoreDidJwk.getData().did)
this.did = rustCoreDidJwk.getData().did
this.document = rustCoreDidJwk.getData().document
}

Expand All @@ -38,7 +38,7 @@ class DidJwk {
constructor(uri: String) {
val rustCoreDidJwk = RustCoreDidJwk.fromUri(uri)

this.did = Did.fromRustCore(rustCoreDidJwk.getData().did)
this.did = rustCoreDidJwk.getData().did
this.document = rustCoreDidJwk.getData().document
}

Expand Down
Loading

0 comments on commit 1155fed

Please sign in to comment.