オフィスアワーがそろそろ始まるよ!()

crypto

暗号化に関するモジュールです。

ノート: 以下のコードサンプルではテスト用のヘルパー関数equalByteStringを使用しています。

ハッシュ関数

MD5

MD5暗号化ハッシュ関数です。単発のハッシュ取得は、Md5の関数hashを使います。

  • hash(b: []const u8, out: []u8) void: bをハッシュ関数にかけ、outに出力します。

examples/ch09-std/crypto/src/md5.zen:4:11

const Md5 = std.crypto.Md5;
test "MD5" {
    const expected = "0cc175b9c0f1b6a831c399e269772661";
    var hashed:[16]u8 = undefined;
    Md5.hash("a", hashed[0..]);
    
    equalByteString(expected, hashed);
}

Md5のインスタンスは内部にストリームバッファを持つため、ストリームに対してハッシュ関数を適用することもできます。resetでバッファを初期化、updateでバッファを更新、finalでハッシュ値の取得、を行います。

  • init() Md5: 新しくMd5のインスタンスを作成します。
  • reset() void: ストリームバッファを初期化します。
  • update(b: []const u8) void: ストリームバッファを更新します。
  • final(out: []u8) void: ストリームバッファの内容から、ハッシュ値を計算します。

sha1

SHA-1暗号化ハッシュ関数です。単発のハッシュ取得は、Sha1の関数hashを使います。

  • hash(b: []const u8, out: []u8) void: bをハッシュ関数にかけ、outに出力します。

examples/ch09-std/crypto/src/sha1.zen:4:11

const Sha1 = std.crypto.Sha1;
test "SHA-1" {
    const expected = "a9993e364706816aba3e25717850c26c9cd0d89d";
    var hashed:[20]u8 = undefined;
    Sha1.hash("abc", hashed[0..]);
    
    equalByteString(expected, hashed);
}

ストリームに対してハッシュ関数を適用することもできます。

  • init() Sha1: 新しくSha1のインスタンスを作成します。
  • reset() void: ストリームバッファを初期化します。
  • update(b: []const u8) void: ストリームバッファを更新します。
  • final(out: []u8) void: ストリームバッファの内容から、ハッシュ値を計算します。

sha2

SHA-2暗号化ハッシュ関数です。ハッシュ長の違いでSha224Sha256Sha384Sha512があります。

  • hash(b: []const u8, out: []u8) void: bをハッシュ関数にかけ、outに出力します。

examples/ch09-std/crypto/src/sha2.zen:4:11

const Sha224 = std.crypto.Sha224;
test "SHA-2" {
    const expected = "23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7";
    var hashed:[28]u8 = undefined;
    Sha224.hash("abc", hashed[0..]);
    
    equalByteString(expected, hashed);
}

ストリームに対してハッシュ関数を適用することもできます。

  • init() Sha224init() Sha256init() Sha384init() Sha512: 新しいインスタンスを作成します。
  • reset() void: ストリームバッファを初期化します。
  • update(b: []const u8) void: ストリームバッファを更新します。
  • final(out: []u8) void: ストリームバッファの内容から、ハッシュ値を計算します。

sha3

SHA-3暗号化ハッシュ関数です。ハッシュ長の違いでSha3_224Sha3_256Sha3_384Sha3_512があります。

  • hash(b: []const u8, out: []u8) void: bをハッシュ関数にかけ、outに出力します。

ストリームに対してハッシュ関数を適用することもできます。

  • init() Sha3_224init() Sha3_256init() Sha3_384init() Sha3_512: 新しいインスタンスを作成します。
  • reset() void: ストリームバッファを初期化します。
  • update(b: []const u8) void: ストリームバッファを更新します。
  • final(out: []u8) void: ストリームバッファの内容から、ハッシュ値を計算します。

gimli

Gimliハッシュです。

  • hash(out: []u8, in: []const u8) void: bをハッシュ関数にかけ、outに出力します。

examples/ch09-std/crypto/src/gimli.zen:4:12

const crypto = std.crypto;
test "gimli" {
    // a test vector (30) from NIST KAT submission.
    var msg: [29]u8 = undefined;
    try std.fmt.hexToBytes(&msg, "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C");
    var md: [32]u8 = undefined;
    crypto.gimli.hash(&md, msg);
    equalByteString("1C9A03DC6A5DDC5444CFC6F4B154CFF5CF081633B2CEA4D7D0AE7CCFED5AAA44", md);
}

blake2

BLAKE2暗号化ハッシュ関数です。ハッシュ長の違いでBlake2s224Blake2s256Blake2b384Blake2b512があります。

examples/ch09-std/crypto/src/blake2.zen:4:11

const Blake2s224 = std.crypto.Blake2s224;
test "blake2" {
    const expected = "0b033fc226df7abde29f67a05d3dc62cf271ef3dfea4d387407fbd55";
    var hashed:[28]u8 = undefined;
    Blake2s224.hash("abc", hashed[0..]);
    
    equalByteString(expected, hashed);
}

ストリームに対してハッシュ関数を適用することもできます。

  • init() Blake2s224init() Blake2s256init() Blake2b384init() Blake2b512: 新しいインスタンスを作成します。
  • reset() void: ストリームバッファを初期化します。
  • update(b: []const u8) void: ストリームバッファを更新します。
  • final(out: []u8) void: ストリームバッファの内容から、ハッシュ値を計算します。

メッセージ認証符号

hmac

メッセージ認証符号HMACです。ハッシュ関数の違いで、HmacMd5HmacSha1HmacSha256HmacBlake2s256があります。

examples/ch09-std/crypto/src/hmac.zen:4:9

const HmacMd5 = std.crypto.HmacMd5;
test "hmac md5" {
    var out: [HmacMd5.mac_length]u8 = undefined;
    HmacMd5.create(out[0..], "The quick brown fox jumps over the lazy dog", "key");
    equalByteString("80070713463e7749b90c2dc24911e275", out[0..]);
}

Poly1305

メッセージ認証符号Poly1305です。

examples/ch09-std/crypto/src/poly1305.zen:4:16

const Poly1305 = std.crypto.Poly1305;
test "crypto.poly1305 " {
    const expected_mac = "\xa8\x06\x1d\xc1\x30\x51\x36\xc6\xc2\x2b\x8b\xaf\x0c\x01\x27\xa9";

    const msg = "Cryptographic Forum Research Group";
    const key = "\x85\xd6\xbe\x78\x57\x55\x6d\x33\x7f\x44\x52\xfe\x42\xd5\x06\xa8" ++
        "\x01\x03\x80\x8a\xfb\x0d\xb2\xfd\x4a\xbf\xf6\xaf\x41\x49\xf5\x1b";

    var mac: [16]u8 = undefined;
    Poly1305.create(mac[0..], msg, key);

    equalSlices(u8, expected_mac, mac);
}

ストリーム暗号

chaCha20IETF

ストリーム暗号ChaCha20です。NONCEのビット幅の違いで、chaCha20IETFchaCha20With64BitNonceがあります。

examples/ch09-std/crypto/src/chacha20.zen:4:44

const chaCha20IETF = std.crypto.chaCha20IETF;
test "crypto.chacha20" {
    const expected_result = [_]u8{
        0x6e, 0x2e, 0x35, 0x9a, 0x25, 0x68, 0xf9, 0x80,
        0x41, 0xba, 0x07, 0x28, 0xdd, 0x0d, 0x69, 0x81,
        0xe9, 0x7e, 0x7a, 0xec, 0x1d, 0x43, 0x60, 0xc2,
        0x0a, 0x27, 0xaf, 0xcc, 0xfd, 0x9f, 0xae, 0x0b,
        0xf9, 0x1b, 0x65, 0xc5, 0x52, 0x47, 0x33, 0xab,
        0x8f, 0x59, 0x3d, 0xab, 0xcd, 0x62, 0xb3, 0x57,
        0x16, 0x39, 0xd6, 0x24, 0xe6, 0x51, 0x52, 0xab,
        0x8f, 0x53, 0x0c, 0x35, 0x9f, 0x08, 0x61, 0xd8,
        0x07, 0xca, 0x0d, 0xbf, 0x50, 0x0d, 0x6a, 0x61,
        0x56, 0xa3, 0x8e, 0x08, 0x8a, 0x22, 0xb6, 0x5e,
        0x52, 0xbc, 0x51, 0x4d, 0x16, 0xcc, 0xf8, 0x06,
        0x81, 0x8c, 0xe9, 0x1a, 0xb7, 0x79, 0x37, 0x36,
        0x5a, 0xf9, 0x0b, 0xbf, 0x74, 0xa3, 0x5b, 0xe6,
        0xb4, 0x0b, 0x8e, 0xed, 0xf2, 0x78, 0x5e, 0x42,
        0x87, 0x4d,
    };
    const input = "Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it.";
    var result: [114]u8 = undefined;
    const key = [_]u8{
        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,
    };
    const nonce = [_]u8{
        0, 0, 0, 0,
        0, 0, 0, 0x4a,
        0, 0, 0, 0,
    };

    chaCha20IETF(result[0..], input[0..], 1, key, nonce);
    equalSlices(u8, expected_result, result);

    // Chacha20 is self-reversing.
    var plaintext: [114]u8 = undefined;
    chaCha20IETF(plaintext[0..], result[0..], 1, key, nonce);
    equalSlices(u8, input, plaintext);
}

ディフィー・ヘルマン鍵共有

X25519

Curve25519を利用して実現されるディフィー・ヘルマン鍵共有方式です。

  • createPublicKey(public_key: []u8, private_key: []const u8) bool: 秘密鍵 (private_key) から、公開鍵 (public_key) を生成します。公開鍵のバイト列が全て0になった場合falseが返ります。
  • create(out: []u8, private_key: []const u8, public_key: []const u8) bool: 秘密鍵 (private_key) と公開鍵 (public_key) のペアから共有鍵を生成します。共有鍵のバイト列が全て0になった場合falseが返ります。

乱数生成

  • randomBytes(buf: []u8) GetRandomError!void: OSの乱数生成機能を使って、ランダムに生成されたバイト列を生成します。

☰ 人の生きた証は永遠に残るよう ☰
Copyright © 2018-2019 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.