random.scm 3.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. ;;; guile-gcrypt --- crypto tooling for guile
  2. ;;; Copyright © 2016 Christopher Allan Webber <cwebber@dustycloud.org>
  3. ;;; Copyright © 2019 Mathieu Othacehe <m.othacehe@gmail.com>
  4. ;;;
  5. ;;; This file is part of guile-gcrypt.
  6. ;;;
  7. ;;; guile-gcrypt is free software; you can redistribute it and/or modify it
  8. ;;; under the terms of the GNU General Public License as published by
  9. ;;; the Free Software Foundation; either version 3 of the License, or
  10. ;;; (at your option) any later version.
  11. ;;;
  12. ;;; guile-gcrypt is distributed in the hope that it will be useful, but
  13. ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
  14. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. ;;; General Public License for more details.
  16. ;;;
  17. ;;; You should have received a copy of the GNU General Public License
  18. ;;; along with guile-gcrypt. If not, see <http://www.gnu.org/licenses/>.
  19. (define-module (gcrypt random)
  20. #:use-module (gcrypt internal)
  21. #:use-module (gcrypt base64)
  22. #:use-module (rnrs bytevectors)
  23. #:use-module (system foreign)
  24. #:use-module (ice-9 match)
  25. #:export (%gcry-weak-random
  26. %gcry-strong-random
  27. %gcry-very-strong-random
  28. gen-random-bv
  29. random-token))
  30. (define %gcry-weak-random 0) ; not used
  31. (define %gcry-strong-random 1)
  32. (define %gcry-very-strong-random 2)
  33. (define %gcry-randomize
  34. (libgcrypt->procedure void
  35. "gcry_randomize"
  36. `(* ,size_t ,int))) ; buffer, length, level
  37. (define* (gen-random-bv #:optional (bv-length 50)
  38. (level %gcry-strong-random))
  39. (let* ((bv (make-bytevector bv-length))
  40. (bv-ptr (bytevector->pointer bv)))
  41. (%gcry-randomize bv-ptr bv-length %gcry-strong-random)
  42. bv))
  43. (define %gcry-create-nonce
  44. (libgcrypt->procedure void "gcry_create_nonce"
  45. `(* ,size_t))) ; buffer, length
  46. (define* (gen-random-nonce #:optional (bv-length 50))
  47. (let* ((bv (make-bytevector bv-length))
  48. (bv-ptr (bytevector->pointer bv)))
  49. (%gcry-create-nonce bv-ptr bv-length)
  50. bv))
  51. (define* (random-token #:optional (bv-length 30)
  52. (type 'strong))
  53. "Generate a random token.
  54. Generates a token of bytevector BV-LENGTH, default 30.
  55. The default TYPE is 'strong. Possible values are:
  56. - strong: Uses libgcrypt's gcry_randomize procedure with level
  57. GCRY_STRONG_RANDOM (\"use this level for session keys and similar
  58. purposes\").
  59. - very-strong: Also uses libgcrypt's gcry_randomize procedure with level
  60. GCRY_VERY_STRONG_RANDOM (\"Use this level for long term key material\")
  61. - nonce: Uses libgcrypt's gcry_xcreate_nonce, whose documentation I'll
  62. just quote inline:
  63. Fill BUFFER with LENGTH unpredictable bytes. This is commonly
  64. called a nonce and may also be used for initialization vectors and
  65. padding. This is an extra function nearly independent of the other
  66. random function for 3 reasons: It better protects the regular
  67. random generator's internal state, provides better performance and
  68. does not drain the precious entropy pool."
  69. (let ((bv (match type
  70. ('strong
  71. (gen-random-bv bv-length %gcry-strong-random))
  72. ('very-strong
  73. (gen-random-bv bv-length %gcry-very-strong-random))
  74. ('nonce
  75. (gen-random-nonce bv-length)))))
  76. (base64-encode bv 0 bv-length #f #t base64url-alphabet)))