Interfacez-les tous !
WASM Interface Types : la promesse de l'universel
@m4d_zhttps://talks.m4dz.net/wasm-types/fr/Une app
de messagerie
Mais voilà, on a un problème…
Zero Knowledge Architecture
Du coup, on a un problème :
JS est lent
(bah oui, quand même)
ASM.js : l’expérience
Emscripten
$ emcc hello_world.c
$ tree
.
├── a.out.html
└── a.out.js
$ node a.out.js
Hello World!
Et si on pouvait compiler
toute notre codebase Web ?
WebAssembly,
des modules pour tout changer
WASM Binary Format
0061 736d
0100 0000
0100 01
6002
7f7f
017f 07
0300 01
0002
0700 0103
6164 64
0000 07
0a00 0100
00
2000 2001
6a0b 0709
0000 04
6e61 6d65
WASM Text Format
(module
(func (export "add") (param i32 i32) (result i32)
local.get 0
local.get 1
i32.add))
Donc on a des modules
La Sandbox
Modèle de sécurité
PWA :
le chiffrement sécurisé
Utiliser un module WASM ?
Libsodium:
le chiffrement moderne
Libsodium + emscripten =
WASM Crypto Module
JS Module
const _sodium = require('libsodium-wrappers');
(async() => {
await _sodium.ready;
const sodium = _sodium;
console.log(sodium.VERSION);
})();
Clef Publique / Clef privée : Késako?
Chiffrement à clef publique
const SK = /* DONALD SECRET KEY */;
const PK = /* BORIS PUBLIC KEY */;
const _sodium = require('libsodium-wrapper');
let message = /* Never Gonna Give You Up! */;
(async () => {
await _sodium.ready; const sodium = _sodium;
const nonce = sodium.randombytes_buf(sodium.crypto_secretbox_NONCEBYTES);
const boris_pubkey = sodium.from_hex(PK);
const donald_seckey = sodium.from_hex(SK);
let ciphered = sodium.crypto_box_easy(message, nonce, boris_pubkey, donald_seckey);
let payload = nonce.concat(ciphered);
});
To Web, or not to Web?
(le serveur n’accède pas aux contenus en ZKA)
Binders!
Problème : la lib doit être
compilée nativement (node-gyp)
WASM hors du navigateur:
WASI
C’est le 5e Beatles
la 3e promesse de WASM
Securité
Problème :
WASM est en MVP
🍀 static types
I need Strings
💩 UTF-8
Linear Memory!
(un entier, c’est un pointeur mémoire)
Passage de valeurs depuis WASM vers JS :
simple mais fastidieux
(on a tout hardcodé dans le moteur)
Passage de valeurs depuis WASM
vers n’importe quoi :
on ne va pas hardcoder tous les codex
Besoin d’interfaces pour les I/O
(ce que fait WASI niveau système)
The System Interface
WASM Interface Types
(traits)
Defines shared behavior in an abstract way
.WITX
Mon app offre une couche crypto unifiée
(avec le module libsodium dessous)
WITX: Interface Types Definition
;;; file://src/types/crypto.witx`
(use "errno.witx")
;;; Encoder
(module $crypto
(@interface func (export "encode")
(param $lh s32)
(param $rh s32)
(result $error $errno)
(result $res s32)
)
)
Rust à la rescousse:
Wiggle
Import
/// file://src/lib/main.rs
wiggle::from_witx!({
witx: ["../types/crypto.witx"],
ctx: CryptoCtx,
});
pub struct CryptoCtx {}
Implement
/// file://src/lib/main.rs
impl crypto::Crypto for CryptoCtx {
fn encode(&self, lh: i32, rh: i32) -> Result<i32, types::Errno> {
// Uses libsodium
}
}
Link: Wasmtime linker
/// file://src/lib/main.rs
let mut linker = Linker::new(store);
linker.func("crypto", "encode", |x: i32, y: i32| {
let ctx = crypto::CryptoCtx {};
ctx.encode(x, y).unwrap()
})?;
linker.instantiate(&module)
Usage
/// file://src/app/messages_crypto.rs
#[link(wasm_import_module = "crypto")]
extern "C" {
fn encode(lh: i32, rh: i32) -> i32;
}
#[no_mangle]
pub unsafe extern "C" fn enc_message(lh: i32, rh: i32) -> i32 {
encode(lh, rh)
}
Alt Usage: WAT
;;; file://src/app/messages_crypto.wat
(module
(import "crypto" "encode" (func $crypto_encode (param i32 i32) (result i32)))
(func $enc_message (param $lhs i32) (param $rhs i32) (result i32)
local.get $lhs
local.get $rhs
call $crypto_encode)
(export "enc_message" (func $enc_message))
)
Oui, mais…
Example : API Python
### file://src/api/messages_backend.py
import wasmtime
# Load our `crypto.wasm` file.
# This is loaded by the `wasmtime_py`.
import crypto
# Use it!
crypto.encode(a, b)
Write Once,
Run Anywhere
Le futur du Serverless (FaaS)
$ curl --location --request POST 'https://[::]/api/executables' \
--header 'Content-Type: application/octet-stream' \
--header 'SSVM_Description: Encoder' \
--data-binary 'crypto.wasm'
$ curl --location --request POST 'https://[::]/api/run/123/encode' \
--header 'Content-Type: text/plain' \
--data-raw "bXkgc2Vuc2l0aXZlIGRvY3VtZW50LmRvY3gK"
Open Standard
→ Bâtir l’écosystème
Paranoïd Web Dino · Tech Evangelist
https://talks.m4dz.net/wasm-types/fr/ Disponible sous licence CC BY-SA 4.0
m4dz, CC BY-SA 4.0
Courtesy of Unsplash and Pexels contributors
Powered by Reveal.js
Source code available at
https://git.madslab.net/talks