ZenとCとが混在するプロジェクトをビルドスクリプトで取り扱うことができます。ここではそのようなプロジェクトのビルドスクリプトを作成します。
Zenの標準ライブラリには暗号化モジュールが含まれています。これをC言語から使うサンプルコードを考えます。
Zen標準ライブラリにあるChaCha20
というアルゴリズムで暗号化、復号化します。このアルゴリズムを深く理解する必要はありませんが、サンプルコードの理解のために少しだけ説明します。
ChaCha20
の特徴は、同じパラメータを渡すと、暗号化と復号化が同じアルゴリズムでできる、ということです。つまり、平文とパラメータとをアルゴリズムにかけることで暗号文を得られ、その暗号文と暗号化時のパラメータとを再度アルゴリズムにかけることで平文を復元できます。
ChaCha20
で暗号化 / 復号化する関数はstd.crypto.chaCha20IETF
です。この関数をC言語から呼び出せるように、Zen側にラッパー関数chacha20
をsrc/crypto.zen
に用意します。処理内容は、C言語から受け取ったポインタを、chaCha20IETF
が要求するスライスやZenの配列に変換しているだけです。
examples/ch14-c/mixing/src/crypto.zen:3:20
const chaCha20IETF = std.crypto.chaCha20IETF;
export fn chacha20(
out_ptr: [*]mut u8,
in_ptr: [*]u8,
len: usize,
counter: u32,
key_ptr: [*]u8,
nonce_ptr: [*]u8,
) void {
const out = out_ptr[0..len];
const in = in_ptr[0..len];
const key = @ptrCast(*[32]u8, key_ptr[0..32]);
const nonce = @ptrCast(*[12]u8, nonce_ptr[0..12]);
// Zenの標準ライブラリにある暗号化関数
chaCha20IETF(out, in, counter, key.*, nonce.*);
}
chacha20
関数を呼び出すCソースファイルsrc/main.c
を用意します。2回関数を呼び出し、平文→暗号文→平文と変換し、最後の平文を標準出力に表示します。
examples/ch14-c/mixing/src/main.c:1:36
#include <stdio.h>
#include <string.h>
// `crypto.zen`のビルドで自動生成されるヘッダ
#include <crypto.h>
int main(void) {
// 暗号化するテキスト
char plain_text[] = "Zen encrypts me!";
// 暗号化の準備
uintptr_t len = strlen(plain_text);
uint8_t crypted[len];
uint8_t key[] = {
0, 1, 2, 3, 4, 5, 6, 7,
8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23,
24, 25, 26, 27, 28, 29, 30, 31,
};
uint8_t nonce[] = {
0, 0, 0, 0,
0, 0, 0, 0x4a,
0, 0, 0, 0,
};
// Zenの`chacha20`を呼び出して暗号化
chacha20(crypted, (uint8_t*)plain_text, len, 1, key, nonce);
// Zenの`chacha20`を呼び出して復号化
uint8_t decrypted[len];
chacha20(decrypted, crypted, len, 1, key, nonce);
// 暗号化前と同じ文字列"Zen encrypts me!"が出力される
fwrite(decrypted, len, 1, stdout);
printf("\n");
return 0;
}
これらのZenソースファイルとCソースファイルをビルドするためのビルドスクリプトbuild.zen
は次の通りです。
examples/ch14-c/mixing/build.zen:1:13
const Builder = @import("std").build.Builder;
pub fn build(b: *mut Builder) void {
// `crypto.zen`のオブジェクトファイルを作成する
// `crypto.h`が自動生成される
const obj = b.addObject("crypto", "src/crypto.zen");
// C言語のソースファイルから実行ファイルをビルドする
const exe = b.addExecutable("zen_crypto", null);
exe.addCSourceFile("src/main.c", &[_][]u8{"-std=c11"});
// `crypto.zen`のオブジェクトファイルをビルド対象に追加する
exe.addObject(obj);
exe.linkSystemLibrary("c");
exe.install();
}
ビルドして、実行します。
$ zen build
$ ./zen-cache/bin/zen_crypto
Zen encrypts me!
このようにZenのビルドスクリプトには、ZenソースファイルとCソースファイルを同時にビルドするための仕組みが備わっています。
☰ 人の生きた証は永遠に残るよう ☰
Copyright © 2018-2020 connectFree Corporation. All rights reserved. | 特定商取引法に基づく表示
Zen, the Zen three-circles logo and The Zen Programming Language are trademarks of connectFree corporation in Japan and other countries.