Rill v0.13 Reference

Standard library · Cryptography

crypto/passwd

Imported as import "crypto/passwd" as passwd, its names are then passwd.…. Every signature below is the one the checker infers.

Functions

fn hmac_sha1(key: Str, msg: Str) -> Str

HMAC-SHA-1. A key longer than the block is hashed down to fit; a shorter one is padded with zeros, which is why a key of nulls and an empty key are the same key — a property of the construction, not of this writing of it.

passwd.to_hex(passwd.hmac_sha1("key", "The quick brown fox jumps over the lazy dog"))   # => de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9

fn xor_byte(s: Str, b: Int) -> Str

Every byte of a string against one constant. The pads of HMAC are nothing more than this.

passwd.xor_byte("AB", 32)   # => ab

fn xor_str(a: Str, b: Str) -> Str

Two strings of the same length, byte against byte. PBKDF2 folds its rounds together this way.

passwd.to_hex(passwd.xor_str("AB", "  "))   # => 6162

fn pbkdf2_sha1(key: Str, salt: Str, rounds: Int) -> Str

PBKDF2-HMAC-SHA-1, one block of it: twenty bytes, which is all this asks for and all a SHA-1 has to give. The block index the specification appends is therefore always one.

rounds is a count, not a duration. It is written down where the accounts are made rather than here, so that raising it later is one number in one place — and so that a stored password can say which count made it.

passwd.to_hex(passwd.pbkdf2_sha1("password", "salt", 2))   # => ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957

fn to_hex(s: Str) -> Str

passwd.to_hex("AZ")   # => 415a

fn from_hex(s: Str) -> Str

passwd.from_hex("415a")   # => AZ

fn same_secret(a: Str, b: Str) -> Int

Whether two secrets are the same, in a time that does not depend on how far along they first differ.

The obvious a == b returns the moment it finds a mismatched byte, and how long it took is a measurement of how much of the answer was right — over enough tries, that is the answer. This walks both in full and folds the differences together. Unequal lengths are refused up front: that much is public, since the length of a hash is a constant of the scheme.

passwd.same_secret("abc", "abc")    # => 1
passwd.same_secret("abc", "abd")    # => 0
passwd.same_secret("abc", "abcd")   # => 0