Skip to main content

Crypto for WASI

While optimizing compilers could allow efficient implementation of cryptographic features in WebAssembly, there are several occasions where a host implementation is more desirable. WASI-crypto aims to fill those gaps by defining a standard interface as a set of APIs. Currently not support Android.

Make sure you have Rust and WasmEdge installed and the WASI-crypto plugin installed.

Write WebAssembly Using WASI-Crypto

(Optional) Rust Installation

For importing WASI-Crypto in rust, you should use the wasi-crypto binding in your cargo.toml

[dependencies]
wasi-crypto = "0.1.5"

High-Level Operations

Hash Function

IdentifierAlgorithm
SHA-256SHA-256 hash function
SHA-512SHA-512 hash function
SHA-512/256SHA-512/256 hash function with a specific IV
// hash "test" by SHA-256
let hash : Vec<u8> = Hash::hash("SHA-256", b"test", 32, None)?;
assert_eq!(hash.len(), 32);

Message Authentications function

IdentifierAlgorithm
HMAC/SHA-256RFC2104 MAC using the SHA-256 hash function
HMAC/SHA-512RFC2104 MAC using the SHA-512 hash function
// generate key
let key = AuthKey::generate("HMAC/SHA-512")?;
// generate tag
let tag = Auth::auth("test", &key)?;
// verify
Auth::auth_verify("test", &key, tag)?;

Key Driven function

IdentifierAlgorithm
HKDF-EXTRACT/SHA-256RFC5869 EXTRACT function using the SHA-256 hash function
HKDF-EXTRACT/SHA-512RFC5869 EXTRACT function using the SHA-512 hash function
HKDF-EXPAND/SHA-256RFC5869 EXPAND function using the SHA-256 hash function
HKDF-EXPAND/SHA-512RFC5869 EXPAND function using the SHA-512 hash function

Example:

let key = HkdfKey::generate("HKDF-EXTRACT/SHA-512")?;
let prk = Hkdf::new("HKDF-EXPAND/SHA-512", &key, Some(b"salt"))?;
let derived_key = prk.expand("info", 100)?;
assert_eq!(derived_key.len(), 100);

Signatures Operation

IdentifierAlgorithm
ECDSA_P256_SHA256ECDSA over the NIST p256 curve with the SHA-256 hash function
ECDSA_K256_SHA256ECDSA over the secp256k1 curve with the SHA-256 hash function
Ed25519Edwards Curve signatures over Edwards25519 (pure EdDSA) as specified in RFC8032
RSA_PKCS1_2048_SHA256RSA signatures with a 2048 bit modulus, PKCS1 padding and the SHA-256 hash function
RSA_PKCS1_2048_SHA384RSA signatures with a 2048 bit modulus, PKCS1 padding and the SHA-384 hash function
RSA_PKCS1_2048_SHA512RSA signatures with a 2048 bit modulus, PKCS1 padding and the SHA-512 hash function
RSA_PKCS1_3072_SHA384RSA signatures with a 3072 bit modulus, PKCS1 padding and the SHA-384 hash function
RSA_PKCS1_3072_SHA512RSA signatures with a 3072 bit modulus, PKCS1 padding and the SHA-512 hash function
RSA_PKCS1_4096_SHA512RSA signatures with a 4096 bit modulus, PKCS1 padding and the SHA-512 hash function
RSA_PSS_2048_SHA256RSA signatures with a 2048 bit modulus, PSS padding and the SHA-256 hash function
RSA_PSS_2048_SHA384RSA signatures with a 2048 bit modulus, PSS padding and the SHA-384 hash function
RSA_PSS_2048_SHA512RSA signatures with a 2048 bit modulus, PSS padding and the SHA-512 hash function
RSA_PSS_3072_SHA384RSA signatures with a 2048 bit modulus, PSS padding and the SHA-384 hash function
RSA_PSS_3072_SHA512RSA signatures with a 3072 bit modulus, PSS padding and the SHA-512 hash function
RSA_PSS_4096_SHA512RSA signatures with a 4096 bit modulus, PSS padding and the SHA-512 hash function

Example:

let pk = SignaturePublicKey::from_raw("Ed25519", &[0; 32])?;

let kp = SignatureKeyPair::generate("Ed25519")?;
let signature = kp.sign("hello")?;

kp.publickey()?.signature_verify("hello", &signature)?;