Skip to content

Commit

Permalink
add crypto docs (#357)
Browse files Browse the repository at this point in the history
  • Loading branch information
nitro-neal authored Sep 17, 2024
1 parent c146f38 commit 866f768
Show file tree
Hide file tree
Showing 10 changed files with 491 additions and 10 deletions.
29 changes: 27 additions & 2 deletions bound/kt/src/main/kotlin/web5/sdk/crypto/keys/Jwk.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,15 @@ import web5.sdk.rust.JwkData as RustCoreJwkData
import web5.sdk.rust.Web5Exception.Exception as RustCoreException

/**
* Partial representation of a [JSON Web Key as per RFC7517](https://tools.ietf.org/html/rfc7517).
* Note that this is a subset of the spec.
* Represents a JSON Web Key (JWK) as per [RFC7517](https://tools.ietf.org/html/rfc7517).
* This is a partial representation, containing key parameters such as `alg`, `kty`, `crv`, and key material like `x`, `y`, and `d`.
*
* @property alg The algorithm intended for use with the key (optional).
* @property kty The key type (e.g., `EC`, `OKP`).
* @property crv The curve used with the key (e.g., `Ed25519`, `X25519`).
* @property x The `x` coordinate for elliptic curve keys, or the public key for OKP keys.
* @property y The `y` coordinate for elliptic curve keys (optional).
* @property d The private key material, if present (optional).
*/
data class Jwk (
val alg: String? = null,
Expand All @@ -17,6 +24,7 @@ data class Jwk (
val y: String? = null,
val d: String? = null
) {
// Internal representation of the JWK for use with Rust core logic.
internal val rustCoreJwkData: RustCoreJwkData = RustCoreJwkData(
alg,
kty,
Expand All @@ -27,6 +35,14 @@ data class Jwk (
)

companion object {
/**
* Converts a Rust core `JwkData` object into a Kotlin `Jwk` object.
*
* This is an internal method for transforming the Rust core JWK structure into the Kotlin equivalent.
*
* @param rustCoreJwkData The JWK data from Rust core.
* @return A Kotlin `Jwk` object.
*/
internal fun fromRustCoreJwkData(rustCoreJwkData: RustCoreJwkData): Jwk {
return Jwk(
rustCoreJwkData.alg,
Expand All @@ -39,6 +55,15 @@ data class Jwk (
}
}

/**
* Computes the thumbprint of the JWK.
*
* A thumbprint is a cryptographic hash that uniquely identifies the JWK based on its key type and key material.
* This method utilizes Rust core logic to compute the thumbprint.
*
* @return A base64url-encoded thumbprint string.
* @throws Web5Exception If an error occurs during thumbprint computation.
*/
fun computeThumbprint(): String {
try {
val rustCoreJwk = RustCoreJwk(rustCoreJwkData)
Expand Down
52 changes: 52 additions & 0 deletions bound/kt/src/main/kotlin/web5/sdk/crypto/keys/KeyManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,30 +8,82 @@ import web5.sdk.rust.JwkData as RustCoreJwkData
import web5.sdk.rust.KeyManager as RustCoreKeyManager
import web5.sdk.rust.Signer as RustCoreSigner

/**
* Interface representing a key management system.
*
* The `KeyManager` interface defines methods for importing private JSON Web Keys (JWKs) and retrieving signers for public JWKs.
*/
interface KeyManager {
/**
* Imports a private JWK and returns the corresponding public JWK.
*
* @param privateJwk The private JWK to import.
* @return The public JWK after import.
*/
fun importPrivateJwk(privateJwk: Jwk): Jwk

/**
* Retrieves a signer for a given public JWK.
*
* @param publicJwk The public JWK for which to retrieve the signer.
* @return The signer associated with the public JWK.
*/
fun getSigner(publicJwk: Jwk): Signer
}

/**
* Adapter class to convert a Rust core `KeyManager` to a Kotlin `KeyManager`.
*
* This class provides a bridge between Rust core key management logic and Kotlin key management functionality.
*/
internal class ToOuterKeyManager(private val rustCoreKeyManager: RustCoreKeyManager) : KeyManager {
/**
* Imports a private JWK using Rust core and returns the corresponding public JWK.
*
* @param privateJwk The private JWK to import.
* @return The public JWK after import.
*/
override fun importPrivateJwk(privateJwk: Jwk): Jwk {
val rustCoreJwkData = rustCoreKeyManager.importPrivateJwk(privateJwk.rustCoreJwkData)
return Jwk.fromRustCoreJwkData(rustCoreJwkData)
}

/**
* Retrieves a signer for a given public JWK using Rust core.
*
* @param publicJwk The public JWK for which to retrieve the signer.
* @return The signer associated with the public JWK.
*/
override fun getSigner(publicJwk: Jwk): Signer {
val rustCoreSigner = rustCoreKeyManager.getSigner(publicJwk.rustCoreJwkData)
return ToOuterSigner(rustCoreSigner)
}
}

/**
* Adapter class to convert a Kotlin `KeyManager` to a Rust core `KeyManager`.
*
* This class provides a bridge to adapt Kotlin key management logic for use in Rust core.
*/
internal class ToInnerKeyManager(private val keyManager: KeyManager) : RustCoreKeyManager {
/**
* Imports a private JWK using Kotlin logic and converts it to Rust core format.
*
* @param privateJwk The private JWK in Rust core format.
* @return The public JWK in Rust core format.
*/
override fun importPrivateJwk(privateJwk: JwkData): JwkData {
val rustCoreJwkData = Jwk.fromRustCoreJwkData(privateJwk)
val jwk = keyManager.importPrivateJwk(rustCoreJwkData)
return jwk.rustCoreJwkData
}

/**
* Retrieves a signer for a given public JWK using Kotlin logic and converts it to Rust core format.
*
* @param publicJwk The public JWK in Rust core format.
* @return The signer in Rust core format.
*/
override fun getSigner(publicJwk: RustCoreJwkData): RustCoreSigner {
val jwk = Jwk.fromRustCoreJwkData(publicJwk)
val signer = keyManager.getSigner(jwk)
Expand Down
113 changes: 111 additions & 2 deletions bound/kt/src/main/kotlin/web5/sdk/vc/pex/PresentationDefinition.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,42 @@ import web5.sdk.Web5Exception
import web5.sdk.rust.PresentationDefinition as RustCorePresentationDefinition
import web5.sdk.rust.Web5Exception.Exception as RustCoreException

/**
* Represents a DIF Presentation Definition.
*
* The `PresentationDefinition` outlines the criteria that Verifiable Credentials (VCs) must meet
* for a presentation exchange. It includes input descriptors, submission requirements, and additional metadata.
*
* @property id The unique identifier for the Presentation Definition.
* @property name The name of the Presentation Definition (optional).
* @property purpose The purpose of the Presentation Definition (optional).
* @property inputDescriptors A list of input descriptors that define the criteria for acceptable VCs.
* @property submissionRequirements A list of submission requirements (optional).
*/
data class PresentationDefinition(
val id: String,
val name: String?,
val purpose: String?,
val inputDescriptors: List<InputDescriptor>,
val submissionRequirements: List<SubmissionRequirement>? = null
val submissionRequirements: List<SubmissionRequirement>? = null
) {
internal val rustCorePresentationDefinition = RustCorePresentationDefinition(
Json.stringify(this)
)

/**
* Selects Verifiable Credentials (VCs) that match the input descriptors of the Presentation Definition.
*
* @param vcJwts A list of VC JWTs to validate against the input descriptors.
* @return A list of VC JWTs that satisfy the input descriptors.
* @throws Web5Exception If an error occurs during selection.
*
* @example
* ```
* val matchedVcs = presentationDefinition.selectCredentials(vcJwtList)
* println(matchedVcs) // Output: List of matched VC JWTs
* ```
*/
fun selectCredentials(vcJwts: List<String>): List<String> {
try {
return this.rustCorePresentationDefinition.selectCredentials(vcJwts)
Expand All @@ -24,6 +49,19 @@ val submissionRequirements: List<SubmissionRequirement>? = null
}
}

/**
* Creates a presentation submission from the selected Verifiable Credentials (VCs).
*
* @param vcJwts A list of VC JWTs to create the presentation from.
* @return A `PresentationResult` containing the presentation submission and matched VCs.
* @throws Web5Exception If an error occurs during the creation process.
*
* @example
* ```
* val presentationResult = presentationDefinition.createPresentationFromCredentials(vcJwtList)
* println(presentationResult.presentationSubmission.id) // Output: Presentation submission ID
* ```
*/
fun createPresentationFromCredentials(vcJwts: List<String>): PresentationResult {
try {
val rustCoreJsonSerializedPresentationResult = this.rustCorePresentationDefinition.createPresentationFromCredentials(vcJwts)
Expand All @@ -34,17 +72,41 @@ val submissionRequirements: List<SubmissionRequirement>? = null
}
}

/**
* Represents an input descriptor, which specifies the criteria for acceptable Verifiable Credentials (VCs).
*
* @property id The unique identifier for the input descriptor.
* @property name The name of the input descriptor (optional).
* @property purpose The purpose of the input descriptor (optional).
* @property constraints The constraints that define acceptable fields and filters for the VCs.
*/
data class InputDescriptor(
val id: String,
val name: String? = null,
val purpose: String? = null,
val constraints: Constraints,
)

/**
* Contains the constraints for a given input descriptor.
*
* @property fields A list of fields that define the acceptable values and structure for the Verifiable Credentials (VCs).
*/
data class Constraints(
val fields: List<Field>
)

/**
* Represents a field within a Verifiable Credential (VC) that must match certain criteria.
*
* @property id The unique identifier for the field (optional).
* @property name The name of the field (optional).
* @property path The JSON path to the field within the VC.
* @property purpose The purpose of the field (optional).
* @property filter A filter that defines acceptable values for the field (optional).
* @property optional Indicates if the field is optional (defaults to false).
* @property predicate Indicates if the field is required or preferred.
*/
data class Field(
val id: String? = null,
val name: String? = null,
Expand All @@ -55,18 +117,41 @@ data class Field(
val predicate: Optionality? = null
)

/**
* Defines whether a field is required or preferred.
*/
enum class Optionality {
Required,
Preferred
}

/**
* Represents a filter applied to a field within a Verifiable Credential (VC).
*
* @property type The type of the field (e.g., string, integer) (optional).
* @property pattern A regular expression pattern that the field's value must match (optional).
* @property const A constant value that the field's value must match (optional).
* @property contains A nested filter applied to the field (optional).
*/
data class Filter(
val type: String? = null,
val pattern: String? = null,
val const: String? = null,
val contains: Filter? = null
)

/**
* Represents a submission requirement, which defines how input descriptors must be satisfied.
*
* @property rule The rule that defines how input descriptors must be selected (e.g., All or Pick).
* @property from The source of the input descriptors (optional).
* @property fromNested A nested list of submission requirements (optional).
* @property name The name of the submission requirement (optional).
* @property purpose The purpose of the submission requirement (optional).
* @property count The exact number of input descriptors required (optional).
* @property min The minimum number of input descriptors required (optional).
* @property max The maximum number of input descriptors allowed (optional).
*/
data class SubmissionRequirement(
val rule: SubmissionRequirementRule,
val from: String? = null,
Expand All @@ -78,25 +163,49 @@ data class SubmissionRequirement(
val max: Int? = null
)

/**
* Defines the selection rule for input descriptors.
*/
enum class SubmissionRequirementRule {
All,
Pick
}

/**
* Represents the result of a presentation submission.
*
* @property presentationSubmission The `PresentationSubmission` object containing the submission details.
* @property matchedVcJwts A list of matched VC JWTs that satisfy the input descriptors.
*/
data class PresentationResult(
val presentationSubmission: PresentationSubmission,
val matchedVcJwts: List<String>
)

/**
* Represents the presentation submission, which links input descriptors to the matched Verifiable Credentials (VCs).
*
* @property id The unique identifier for the presentation submission.
* @property definitionId The identifier of the Presentation Definition.
* @property descriptorMap A list of mappings between input descriptors and Verifiable Credentials (VCs).
*/
data class PresentationSubmission(
val id: String,
val definitionId: String,
val descriptorMap: List<InputDescriptorMapping>
)

/**
* Maps input descriptors to Verifiable Credentials (VCs) in a presentation submission.
*
* @property id The unique identifier of the input descriptor.
* @property format The format of the Verifiable Credential (e.g., jwt_vc).
* @property path The JSON path to the Verifiable Credential within the presentation submission.
* @property pathNested A nested mapping for deeper structures (optional).
*/
data class InputDescriptorMapping(
val id: String,
val format: String,
val path: String,
val pathNested: InputDescriptorMapping? = null
)
)
Loading

0 comments on commit 866f768

Please sign in to comment.