0 branches
Tree Top files
Code
Clone with HTTPS:
56 years ago
..
argon2 all: super_batch6 fixes last Apr 17 22.25 KB
bcrypt all: super_batch3 fixes last Apr 13 7.96 KB
blake3 all: fix tests last Apr 24 62.43 KB
ecdsa all: fix tests last Apr 24 51.04 KB
hmac all: super_batch3 fixes last Apr 13 18.67 KB
md5 crypto: fix md5.v last Apr 24 11.71 KB
pbkdf2 all: super_batch3 fixes last Apr 13 4.88 KB
pem all: super_batch3 fixes last Apr 13 37.68 KB
ripemd160 all: fix tests last Apr 24 8.42 KB
scrypt all: fix tests last Apr 24 16.64 KB
sha1 markused: fix typedefs last Apr 10 32.9 KB
sha256 markused: fix typedefs last Apr 10 67.24 KB
sha512 mysql: fix tests last Apr 18 231.13 KB
aes all: super_batch6 fixes last Apr 17 42.42 KB

Description

crypto is a module that exposes cryptographic algorithms to V programs.

Each submodule implements things differently, so be sure to consider the documentation of the specific algorithm you need, but in general, the method is to create a cipher struct using one of the module functions, and then to call the encrypt or decrypt method on that struct to actually encrypt or decrypt your data.

This module is a work-in-progress. For example, the AES implementation currently requires you to create a destination buffer of the correct size to receive the decrypted data, and the AesCipher encrypt and decrypt functions only operate on the first block of the src.

The implementations here are loosely based on Go's crypto package.

Examples

AES

import crypto.aes
import crypto.rand

fn main() {
    // remember to save this key somewhere if you ever want to decrypt your data
    key := rand.bytes(32)!
    println('KEY: ${key}')

    // this data is one block (16 bytes) big
    mut data := 'THIS IS THE DATA'.bytes()

    println('generating cipher')
    cipher := aes.new_cipher(key)

    println('performing encryption')
    mut encrypted := []u8{len: aes.block_size}
    cipher.encrypt(mut encrypted, data)
    println(encrypted)

    println('performing decryption')
    mut decrypted := []u8{len: aes.block_size}
    cipher.decrypt(mut decrypted, encrypted)
    println(decrypted)

    assert decrypted == data
}

JWT

import crypto.hmac
import crypto.sha256
import encoding.base64
import json
import time

struct JwtHeader {
    alg string
    typ string
}

struct JwtPayload {
    sub  string
    name string
    iat  int
}

fn main() {
    sw := time.new_stopwatch()
    secret := 'your-256-bit-secret'
    token := make_token(secret)
    ok := auth_verify(secret, token)
    pl := decode_payload(token) or { panic(err) }
    dt := sw.elapsed().microseconds()
    println('token: ${token}')
    println('auth_verify(secret, token): ${ok}')
    println('decode_payload(token): ${pl}')
    println('Elapsed time: ${dt} uS')
}

fn make_token(secret string) string {
    header := base64.url_encode(json.encode(JwtHeader{'HS256', 'JWT'}).bytes())
    payload :=
        base64.url_encode(json.encode(JwtPayload{'1234567890', 'John Doe', 1516239022}).bytes())
    signature := base64.url_encode(hmac.new(secret.bytes(), '${header}.${payload}'.bytes(),
        sha256.sum, sha256.block_size))
    jwt := '${header}.${payload}.${signature}'
    return jwt
}

fn auth_verify(secret string, token string) bool {
    token_split := token.split('.')
    signature_mirror := hmac.new(secret.bytes(), '${token_split[0]}.${token_split[1]}'.bytes(),
        sha256.sum, sha256.block_size)
    signature_from_token := base64.url_decode(token_split[2])
    return hmac.equal(signature_from_token, signature_mirror)
}

fn decode_payload(token string) !JwtPayload {
    token_split := token.split('.')
    payload := json.decode(JwtPayload, base64.url_decode_str(token_split[1]))!
    return payload
}

Argon2 Password Hashing

import crypto.argon2

fn main() {
    hash := argon2.generate_from_password('correct horse battery staple'.bytes())!
    println(hash)

    argon2.compare_hash_and_password('correct horse battery staple'.bytes(), hash.bytes())!
}