Skip to content
Switch branches/tags

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

bcrypt hashing for PicoLisp

GitHub release Build Status Dependency Dependency Build status

This library can be used to hash strings (ex: passwords) using bcrypt in PicoLisp.


  1. Requirements
  2. Getting Started
  3. Usage
  4. Examples
  5. Testing
  6. Contributing
  7. License


  • PicoLisp 64-bit v3.1.9+
  • Tested up to PicoLisp v20.6.29, see test runs
  • Git
  • UNIX/Linux development/build tools (gcc, make/gmake, etc..)

Getting Started

These FFI bindings require the bcrypt C library, compiled as a shared library.

  1. Type make to pull and compile the bcrypt C Library.
  2. Include bcrypt.l in your project
  3. Try the examples below

Linking and Paths

Once compiled, the shared library is symlinked as:

.lib/ -> .modules/bcrypt/HEAD/

The bcrypt.l file searches for .lib/, relative to its current directory.


To keep everything updated, type:

git pull && make clean && make


Only the following functions are exported publicly:

  • (gensalt Factor) generates a salt to be used for hashing a string
    • Factor Number: a Number between 4 and 31, defaults to 12 otherwise
  • (hashpw Passwd Salt) hashes a string with the salt provided
    • Passwd String: the String to be hashed
    • Salt String or Number (optional): a hash String or Number used as a cost Factor (will generate a salt automatically if a Number is provided)
  • (compare Passwd Hash) a predicate which compares the password and hash. Returns NIL or T.
    • Passwd String: the password String
    • Hash String: the hashed String of the password
  • (timing Factor) calculates the timing of a password hashing, in seconds. Returns the factor in car and seconds in cdr

Note: These functions are not namespace local symbols, which means they would redefine symbols with the same name in the 'pico namespace.


  • The default cost Factor is 12.
  • As rule of thumb, when using bcrypt to hash passwords, it should take at least 1 second per hash. Adjust the cost Factor based on the result of a few (timing) runs.
  • The 'InternalError message will be thrown if there's an error.


(gensalt Factor)

pil +

(load "bcrypt.l")

-> "$2a$12$mQn1fUDeEZFW74KD5kU6g."

(gensalt 14)
-> "$2a$14$kjOSmjZeLsBdru7NRPEmQu"

(hashpw Passwd Salt)

pil +

(load "bcrypt.l")

(hashpw "changeme")
-> "$2a$12$mmxN/qk8yvfjCx./KXtgfuqnUFsXjYv1ZTZmkMtdQ94rTDngiXpsq"

(hashpw "changeme" 14)
-> "$2a$14$gZLc8eII8kCbXgFp2rUcv.PPr/oPioojVy0yP0HMU6z2La.v4pEnG"

(hashpw "changeme" "$2a$14$kjOSmjZeLsBdru7NRPEmQu")
-> "$2a$14$kjOSmjZeLsBdru7NRPEmQuL5eU5YN4Yb48bD1A0Pxzwu/3G/7kwBy"

(compare Passwd Hash)

pil +

(load "bcrypt.l")

(compare "changeme" "$2a$14$kjOSmjZeLsBdru7NRPEmQuL5eU5YN4Yb48bD1A0Pxzwu/3G/7kwBy")
-> T

(compare "changeme" "$2a$12$2Lgk0P5s5VsxDUM2aa/HFu/6DwHce1lbUwJ1kTm092DwEeDRHHYBy")
-> NIL

(catch 'InternalError (compare "changeme" "I have no idea what i'm doing"))
-> (BcryptError . "Unable to hash password")

(timing Factor)

pil +

(load "bcrypt.l")

-> (12 . 0)

(timing 15)
-> (15 . 4)


This library now comes with full unit tests. To run the tests, type:

make check


If you find any bugs or issues, please create an issue.

If you want to improve this library, please make a pull-request.


MIT License

Copyright (c) 2015-2020 Alexander Williams, Unscramble