Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add secp256k1 signer & verifier, fix serde deserialize optional timestamp bug, add vc verify test vector #350

Merged
merged 6 commits into from
Sep 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions bindings/web5_uniffi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use web5_uniffi_wrapper::{
crypto::{
dsa::{
ed25519::{ed25519_generator_generate, Ed25519Signer, Ed25519Verifier},
secp256k1::{secp256k1_generator_generate, Secp256k1Signer, Secp256k1Verifier},
Signer, Verifier,
},
in_memory_key_manager::InMemoryKeyManager,
Expand Down
13 changes: 13 additions & 0 deletions bindings/web5_uniffi/src/web5.udl
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
namespace web5 {
JwkData ed25519_generator_generate();
JwkData secp256k1_generator_generate();

[Throws=Web5Error]
BearerDid did_jwk_create(DidJwkCreateOptions? options);
Expand Down Expand Up @@ -91,6 +92,18 @@ interface Ed25519Verifier {
void verify(bytes message, bytes signature);
};

interface Secp256k1Signer {
constructor(JwkData private_key);
[Throws=Web5Error]
bytes sign(bytes payload);
};

interface Secp256k1Verifier {
constructor(JwkData public_jwk);
[Throws=Web5Error]
void verify(bytes message, bytes signature);
};

dictionary DidData {
string uri;
string url;
Expand Down
1 change: 1 addition & 0 deletions bindings/web5_uniffi_wrapper/src/crypto/dsa/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pub mod ed25519;
pub mod secp256k1;

use crate::errors::Result;
use std::sync::Arc;
Expand Down
44 changes: 44 additions & 0 deletions bindings/web5_uniffi_wrapper/src/crypto/dsa/secp256k1.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
use super::{Signer, Verifier};
use crate::errors::Result;
use web5::crypto::{
dsa::{
secp256k1::{
Secp256k1Generator as InnerSecp256k1Generator, Secp256k1Signer as InnerSecp256k1Signer,
Secp256k1Verifier as InnerSecp256k1Verifier,
},
Signer as InnerSigner, Verifier as InnerVerifier,
},
jwk::Jwk,
};

pub fn secp256k1_generator_generate() -> Jwk {
InnerSecp256k1Generator::generate()
}

pub struct Secp256k1Signer(pub InnerSecp256k1Signer);

impl Secp256k1Signer {
pub fn new(private_jwk: Jwk) -> Self {
Self(InnerSecp256k1Signer::new(private_jwk))
}
}

impl Signer for Secp256k1Signer {
fn sign(&self, payload: Vec<u8>) -> Result<Vec<u8>> {
Ok(self.0.sign(&payload)?)
}
}

pub struct Secp256k1Verifier(pub InnerSecp256k1Verifier);

impl Secp256k1Verifier {
pub fn new(public_jwk: Jwk) -> Self {
Self(InnerSecp256k1Verifier::new(public_jwk))
}
}

impl Verifier for Secp256k1Verifier {
fn verify(&self, payload: Vec<u8>, signature: Vec<u8>) -> Result<()> {
Ok(self.0.verify(&payload, &signature)?)
}
}
27 changes: 27 additions & 0 deletions bound/kt/src/main/kotlin/web5/sdk/crypto/Secp256k1Generator.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package web5.sdk.crypto

import web5.sdk.Web5Exception
import web5.sdk.crypto.keys.Jwk
import web5.sdk.rust.secp256k1GeneratorGenerate
import web5.sdk.rust.Web5Exception.Exception as RustCoreException

/**
* Generates private key material for secp256k1.
*/
class Secp256k1Generator {
companion object {
/**
* Generate the private key material; return Jwk includes private key material.
*
* @return Jwk the JWK with private key material included.
*/
fun generate(): Jwk {
try {
val rustCoreJwkData = secp256k1GeneratorGenerate()
return Jwk.fromRustCoreJwkData(rustCoreJwkData)
} catch (e: RustCoreException) {
throw Web5Exception.fromRustCore(e)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package web5.sdk.crypto.signers

import web5.sdk.Web5Exception
import web5.sdk.crypto.keys.Jwk
import web5.sdk.rust.Secp256k1Signer as RustCoreSecp256k1Signer
import web5.sdk.rust.Web5Exception.Exception as RustCoreException

/**
* Implementation of Signer for secp256k1.
*/
class Secp256k1Signer(privateJwk: Jwk) : Signer {
private val rustCoreSigner = RustCoreSecp256k1Signer(privateJwk.rustCoreJwkData)

/**
* Implementation of Signer's sign instance method for secp256k1.
*
* @param payload the data to be signed.
* @return ByteArray the signature.
*/
override fun sign(payload: ByteArray): ByteArray {
try {
return rustCoreSigner.sign(payload)
} catch (e: RustCoreException) {
throw Web5Exception.fromRustCore(e)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package web5.sdk.crypto.verifiers

import web5.sdk.Web5Exception
import web5.sdk.crypto.keys.Jwk
import web5.sdk.rust.Secp256k1Verifier as RustCoreSecp256k1Verifier
import web5.sdk.rust.Web5Exception.Exception as RustCoreException

/**
* Implementation of Verifier for secp256k1.
*/
class Secp256k1Verifier(publicJwk: Jwk) : Verifier {
private val rustCoreVerifier = RustCoreSecp256k1Verifier(publicJwk.rustCoreJwkData)

/**
* Implementation of Signer's verify instance method for secp256k1.
*
* @param message the data to be verified.
* @param signature the signature to be verified.
* @throws Web5Exception in the case of a failed verification
*/
override fun verify(message: ByteArray, signature: ByteArray) {
try {
rustCoreVerifier.verify(message, signature)
} catch (e: RustCoreException) {
throw Web5Exception.fromRustCore(e)
}
}
}
Loading
Loading