feat(js): add randomBytes() and hash() functions

This commit is contained in:
nazeh
2024-09-01 18:17:34 +03:00
parent 915ae66f1a
commit 5d9be5c0f0
6 changed files with 81 additions and 24 deletions

View File

@@ -33,9 +33,16 @@ export class PubkyAuthWidget extends LitElement {
canvasRef = createRef();
constructor() {
// TODO: show error if the PubkyClient is not available!
if (!window.pubky) {
throw new Error("window.pubky is unavailable, make sure to import `@synonymdev/pubky` before this web component.")
}
super()
this.open = false;
this.secret = window.pubky.randomBytes(32)
this.channelId = base64url(window.pubky.hash(this.secret))
}
connectedCallback() {
@@ -51,10 +58,10 @@ export class PubkyAuthWidget extends LitElement {
)
: DEFAULT_HTTP_RELAY
const channel = Math.random().toString(32).slice(2);
callbackUrl.pathname = callbackUrl.pathname + "/" + channel
callbackUrl.pathname = callbackUrl.pathname + "/" + this.channelId
this.authUrl = `pubkyauth:///?cb=${callbackUrl.toString()}&caps=${this.caps}`;
this.authUrl = `pubkyauth://${callbackUrl.hostname + callbackUrl.pathname}?capabilities=${this.caps}&secret=${base64url(this.secret)}`;
console.log({ url: this.authUrl });
fetch(callbackUrl)
.catch(error => console.error("PubkyAuthWidget: Failed to subscribe to http relay channel", error))
@@ -278,3 +285,16 @@ export class PubkyAuthWidget extends LitElement {
}
window.customElements.define('pubky-auth-widget', PubkyAuthWidget)
function base64url(input) {
// Convert Uint8Array to a binary string
let binaryString = '';
for (let i = 0; i < input.length; i++) {
binaryString += String.fromCharCode(input[i]);
}
return btoa(binaryString)
.replace(/\+/g, '-') // Replace + with -
.replace(/\//g, '_') // Replace / with _
.replace(/=+$/, '') // Remove padding (i.e., =)
}

View File

@@ -19,14 +19,15 @@ pub fn random_hash() -> Hash {
Hash::from_bytes(rng.gen())
}
pub fn random_bytes<const N: usize>() -> [u8; N] {
pub fn random_bytes(size: usize) -> Vec<u8> {
let mut rng = rand::thread_rng();
let mut arr = [0u8; N];
let mut arr = vec![0u8; size];
#[allow(clippy::needless_range_loop)]
for i in 0..N {
for i in 0..size {
arr[i] = rng.gen();
}
arr
}

View File

@@ -111,7 +111,7 @@ pub async fn signin(
)?;
}
let session_secret = base32::encode(base32::Alphabet::Crockford, &random_bytes::<16>());
let session_secret = base32::encode(base32::Alphabet::Crockford, &random_bytes(16));
state.db.tables.sessions.put(
&mut wtxn,

View File

@@ -67,22 +67,6 @@ await client.delete(url);
let client = new PubkyClient()
```
#### createRecoveryFile
```js
let recoveryFile = PubkyClient.createRecoveryFile(keypair, passphrase)
```
- keypair: An instance of [Keypair](#keypair).
- passphrase: A utf-8 string [passphrase](https://www.useapassphrase.com/).
- Returns: A recovery file with a spec line and an encrypted secret key.
#### createRecoveryFile
```js
let keypair = PubkyClient.decryptRecoveryfile(recoveryFile, passphrase)
```
- recoveryFile: An instance of Uint8Array containing the recovery file blob.
- passphrase: A utf-8 string [passphrase](https://www.useapassphrase.com/).
- Returns: An instance of [Keypair](#keypair).
#### signup
```js
await client.signup(keypair, homeserver)
@@ -172,6 +156,40 @@ let pubky = publicKey.z32();
```
Returns: The z-base-32 encoded string representation of the PublicKey.
### Helper functions
#### createRecoveryFile
```js
let recoveryFile = createRecoveryFile(keypair, passphrase)
```
- keypair: An instance of [Keypair](#keypair).
- passphrase: A utf-8 string [passphrase](https://www.useapassphrase.com/).
- Returns: A recovery file with a spec line and an encrypted secret key.
#### createRecoveryFile
```js
let keypair = decryptRecoveryfile(recoveryFile, passphrase)
```
- recoveryFile: An instance of Uint8Array containing the recovery file blob.
- passphrase: A utf-8 string [passphrase](https://www.useapassphrase.com/).
- Returns: An instance of [Keypair](#keypair).
#### randomBytes
```js
let bytes = randomBytes(size)
```
Generates random bytes
- size: The number of random bytes to be generated
### hash
```js
let hash = hash(input)
```
Creates a Blake3 hash of the input.
- input: A Uint8Array input to be hashed.
## Test and Development
For test and development, you can run a local homeserver in a test network.

View File

@@ -8,6 +8,7 @@ use wasm_bindgen::prelude::{wasm_bindgen, JsValue};
use crate::PubkyClient;
mod crypto;
mod http;
mod keys;
mod pkarr;

17
pubky/src/wasm/crypto.rs Normal file
View File

@@ -0,0 +1,17 @@
use js_sys::Uint8Array;
use wasm_bindgen::prelude::wasm_bindgen;
/// Generate random bytes.
#[wasm_bindgen(js_name = "randomBytes")]
pub fn random_bytes(size: usize) -> Uint8Array {
pubky_common::crypto::random_bytes(size).as_slice().into()
}
/// Pubky hash function (blake3)
#[wasm_bindgen]
pub fn hash(input: &[u8]) -> Uint8Array {
pubky_common::crypto::hash(input)
.as_bytes()
.as_slice()
.into()
}