Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package guile-gcrypt for openSUSE:Factory checked in at 2022-12-01 18:13:17 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/guile-gcrypt (Old) and /work/SRC/openSUSE:Factory/.guile-gcrypt.new.1835 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "guile-gcrypt" Thu Dec 1 18:13:17 2022 rev:8 rq:1039343 version:0.4.0 Changes: -------- --- /work/SRC/openSUSE:Factory/guile-gcrypt/guile-gcrypt.changes 2020-11-26 23:15:53.833061039 +0100 +++ /work/SRC/openSUSE:Factory/.guile-gcrypt.new.1835/guile-gcrypt.changes 2022-12-01 18:13:18.171531831 +0100 @@ -1,0 +2,10 @@ +Thu Dec 1 15:09:22 UTC 2022 - Jonathan Brielmaier <jbrielma...@opensuse.org> + +- Update to 0.4.0: + * âbase64-encodeâ and âbase64-decodeâ now let you optionally control padding + * New supported algorithms added to (gcrypt hash) + * New supported algorithms added to (gcrypt mac) + * Improvements and fixes to the manual +- Remove no longer needed rpmlintrc + +------------------------------------------------------------------- Old: ---- guile-gcrypt-rpmlintrc v0.3.0.tar.gz New: ---- v0.4.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ guile-gcrypt.spec ++++++ --- /var/tmp/diff_new_pack.o2cwg5/_old 2022-12-01 18:13:19.195537420 +0100 +++ /var/tmp/diff_new_pack.o2cwg5/_new 2022-12-01 18:13:19.231537617 +0100 @@ -1,7 +1,7 @@ # # spec file for package guile-gcrypt # -# Copyright (c) 2020 SUSE LLC +# Copyright (c) 2022 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,14 +17,13 @@ Name: guile-gcrypt -Version: 0.3.0 +Version: 0.4.0 Release: 0 Summary: Cryptography library for Guile using Libgcrypt License: GPL-3.0-or-later Group: Development/Libraries/Other URL: https://notabug.org/cwebber/guile-gcrypt Source0: https://notabug.org/cwebber/%{name}/archive/v%{version}.tar.gz -Source1: guile-gcrypt-rpmlintrc BuildRequires: autoconf BuildRequires: automake BuildRequires: guile-devel >= 2.0.10 ++++++ v0.3.0.tar.gz -> v0.4.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/guile-gcrypt/NEWS new/guile-gcrypt/NEWS --- old/guile-gcrypt/NEWS 2020-05-23 12:23:29.000000000 +0200 +++ new/guile-gcrypt/NEWS 2022-12-01 15:01:20.000000000 +0100 @@ -2,7 +2,7 @@ #+TITLE: Guile-Gcrypt NEWS â history of user-visible changes #+STARTUP: content hidestars -Copyright © 2019, 2020 Ludovic Courtès <l...@gnu.org> +Copyright © 2019, 2020, 2022 Ludovic Courtès <l...@gnu.org> Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright @@ -11,6 +11,11 @@ Run âinfo guile-gcryptâ for details about the changes described below. Please send Guix bug reports to <https://notabug.org/cwebber/guile-gcrypt>. +* Changes in 0.4.0 (since 0.3.0) +** âbase64-encodeâ and âbase64-decodeâ now let you optionally control padding +** New supported algorithms added to (gcrypt hash) +** New supported algorithms added to (gcrypt mac) +** Improvements and fixes to the manual * Changes in 0.3.0 (since 0.2.1) ** âsexp->canonical-sexp->sexpâ now accepts integers ** (gcrypt common) exports âerror/â constants and error handling procedures diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/guile-gcrypt/configure.ac new/guile-gcrypt/configure.ac --- old/guile-gcrypt/configure.ac 2020-05-23 12:23:29.000000000 +0200 +++ new/guile-gcrypt/configure.ac 2022-12-01 15:01:20.000000000 +0100 @@ -1,4 +1,4 @@ -AC_INIT([Guile-Gcrypt], [0.3.0], [guile-u...@gnu.org], +AC_INIT([Guile-Gcrypt], [0.4.0], [guile-u...@gnu.org], [guile-gcrypt], [https://notabug.org/cwebber/guile-gcrypt]) AC_CONFIG_AUX_DIR([build-aux]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/guile-gcrypt/gcrypt/base64.scm new/guile-gcrypt/gcrypt/base64.scm --- old/guile-gcrypt/gcrypt/base64.scm 2020-05-23 12:23:29.000000000 +0200 +++ new/guile-gcrypt/gcrypt/base64.scm 2022-12-01 15:01:20.000000000 +0100 @@ -21,10 +21,10 @@ ;; You should have received a copy of the GNU General Public License ;; along with this program. If not, see <http://www.gnu.org/licenses/>. ;; -;; This file incorporates work covered by the following copyright and +;; This file incorporates work covered by the following copyright and ;; permission notice: ;; -;; Copyright © 2009, 2010 Göran Weinholt <go...@weinholt.se> +;; Copyright © 2009, 2010, 2012, 2013, 2018 Göran Weinholt <go...@weinholt.se> ;; ;; Permission is hereby granted, free of charge, to any person obtaining a ;; copy of this software and associated documentation files (the "Software"), @@ -74,7 +74,11 @@ (define-alias fxior logior) (define-alias fxxor logxor) (define-alias fx=? =) +(define-alias fx<=? <=) +(define-alias fxzero? zero?) (define-alias fx+ +) +(define-alias fx- -) +(define-alias fxmod modulo) (define-alias mod modulo) (define-syntax-rule (assert exp) @@ -147,9 +151,29 @@ (put p #\=))))))) (extract))))) - ;; Decodes a base64 string. The string must contain only pure - ;; unpadded base64 data. - +;; Create a lookup table for the alphabet and remember the latest table. +(define get-decode-table + (let ((ascii-table #f) + (extra-table '()) ;in the unlikely case of unicode chars + (table-alphabet #f)) + (lambda (alphabet) + (unless (eq? alphabet table-alphabet) + ;; Rebuild the table. + (do ((ascii (make-vector 128 #f)) + (extra '()) + (i 0 (+ i 1))) + ((= i (string-length alphabet)) + (set! ascii-table ascii) + (set! extra-table extra)) + (let ((c (char->integer (string-ref alphabet i)))) + (if (fx<=? c 127) + (vector-set! ascii c i) + (set! extra (cons (cons c i) extra))))) + (set! table-alphabet alphabet)) + (values ascii-table extra-table)))) + +;; Decodes a base64 string, optionally ignoring non-alphabet +;; characters and lack of padding. (define base64-decode (case-lambda ((str) @@ -157,97 +181,166 @@ ((str alphabet) (base64-decode str alphabet #f)) ((str alphabet port) - (unless (zero? (mod (string-length str) 4)) - (error 'base64-decode - "input string must be a multiple of four characters")) + (base64-decode str alphabet port #t)) + ((str alphabet port strict?) + (base64-decode str alphabet port strict? #t)) + ((str alphabet port strict? strict-padding?) + (define (pad? c) (eqv? c (char->integer #\=))) (let-values (((p extract) (if port (values port (lambda () (values))) - (open-bytevector-output-port)))) - (do ((i 0 (+ i 4))) - ((= i (string-length str)) - (extract)) - (let ((c1 (string-ref str i)) - (c2 (string-ref str (+ i 1))) - (c3 (string-ref str (+ i 2))) - (c4 (string-ref str (+ i 3)))) - ;; TODO: be more clever than string-index - (let ((i1 (string-index alphabet c1)) - (i2 (string-index alphabet c2)) - (i3 (string-index alphabet c3)) - (i4 (string-index alphabet c4))) - (cond ((and i1 i2 i3 i4) - (let ((x (fxior (fxarithmetic-shift-left i1 18) - (fxarithmetic-shift-left i2 12) - (fxarithmetic-shift-left i3 6) - i4))) - (put-u8 p (fxbit-field x 16 24)) - (put-u8 p (fxbit-field x 8 16)) - (put-u8 p (fxbit-field x 0 8)))) - ((and i1 i2 i3 (char=? c4 #\=) - (= i (- (string-length str) 4))) - (let ((x (fxior (fxarithmetic-shift-left i1 18) - (fxarithmetic-shift-left i2 12) - (fxarithmetic-shift-left i3 6)))) - (put-u8 p (fxbit-field x 16 24)) - (put-u8 p (fxbit-field x 8 16)))) - ((and i1 i2 (char=? c3 #\=) (char=? c4 #\=) - (= i (- (string-length str) 4))) - (let ((x (fxior (fxarithmetic-shift-left i1 18) - (fxarithmetic-shift-left i2 12)))) - (put-u8 p (fxbit-field x 16 24)))) - (else - (error 'base64-decode "invalid input" - (list c1 c2 c3 c4))))))))))) + (open-bytevector-output-port))) + ((ascii extra) (get-decode-table alphabet))) + (define-syntax lookup + (syntax-rules () + ((_ c) (or (and (fx<=? c 127) (vector-ref ascii c)) + (cond ((assv c extra) => cdr) + (else #f)))))) + (let lp-restart ((str str)) + (let* ((len (if strict? + (string-length str) + (let lp ((i (fx- (string-length str) 1))) + ;; Skip trailing invalid chars. + (cond ((fxzero? i) 0) + ((let ((c (char->integer (string-ref str i)))) + (or (lookup c) (pad? c))) + (fx+ i 1)) + (else (lp (fx- i 1)))))))) + (let lp ((i 0)) + (cond + ((fx=? i len) + (extract)) + ((fx<=? i (fx- len 4)) + (let lp* ((c1 (char->integer (string-ref str i))) + (c2 (char->integer (string-ref str (fx+ i 1)))) + (c3 (char->integer (string-ref str (fx+ i 2)))) + (c4 (char->integer (string-ref str (fx+ i 3)))) + (i i)) + (let ((i1 (lookup c1)) (i2 (lookup c2)) + (i3 (lookup c3)) (i4 (lookup c4))) + (cond + ((and i1 i2 i3 i4) + ;; All characters present and accounted for. + ;; The most common case. + (let ((x (fxior (fxarithmetic-shift-left i1 18) + (fxarithmetic-shift-left i2 12) + (fxarithmetic-shift-left i3 6) + i4))) + (put-u8 p (fxbit-field x 16 24)) + (put-u8 p (fxbit-field x 8 16)) + (put-u8 p (fxbit-field x 0 8)) + (lp (fx+ i 4)))) + ((and i1 i2 i3 (pad? c4) (= i (- len 4))) + ;; One padding character at the end of the input. + (let ((x (fxior (fxarithmetic-shift-left i1 18) + (fxarithmetic-shift-left i2 12) + (fxarithmetic-shift-left i3 6)))) + (put-u8 p (fxbit-field x 16 24)) + (put-u8 p (fxbit-field x 8 16)) + (lp (fx+ i 4)))) + ((and i1 i2 (pad? c3) (pad? c4) (= i (- len 4))) + ;; Two padding characters. + (let ((x (fxior (fxarithmetic-shift-left i1 18) + (fxarithmetic-shift-left i2 12)))) + (put-u8 p (fxbit-field x 16 24)) + (lp (fx+ i 4)))) + ((not strict?) + ;; Non-alphabet characters. + (let lp ((i i) (c* '()) (n 4)) + (cond ((fxzero? n) + ;; Found four valid characters. + (lp* (cadddr c*) (caddr c*) (cadr c*) (car c*) + (fx- i 4))) + ((fx=? i len) + (error 'base64-decode + "Invalid input in non-strict mode." + i c*)) + (else + ;; Gather alphabetic (or valid + ;; padding) characters. + (let ((c (char->integer (string-ref str i)))) + (cond ((or (lookup c) + (and (pad? c) + (fx<=? n 2) + (fx=? i (fx- len n)))) + (lp (fx+ i 1) (cons c c*) (fx- n 1))) + (else + (lp (fx+ i 1) c* n)))))))) + (else + (error 'base64-decode + "Invalid input in strict mode." + c1 c2 c3 c4)))))) + ((not strict-padding?) + ;; Append an appropriate amount of padding after the + ;; remaining characters. + (if (<= 2 (- len i) 3) + (lp-restart (string-append (substring str i (string-length str)) + (if (= (- len i) 2) "==" "="))) + (error 'base64-decode "The input is too short." i))) + (else + (error 'base64-decode + "The input is too short, it may be missing padding." + i)))))))))) (define (get-line-comp f port) (if (port-eof? port) (eof-object) (f (get-line port)))) - ;; Reads the common -----BEGIN/END type----- delimited format from - ;; the given port. Returns two values: a string with the type and a - ;; bytevector containing the base64 decoded data. The second value - ;; is the eof object if there is an eof before the BEGIN delimiter. - -(define (get-delimited-base64 port) - (define (get-first-data-line port) - ;; Some MIME data has header fields in the same format as mail - ;; or http. These are ignored. - (let ((line (get-line-comp string-trim-both port))) - (cond ((eof-object? line) line) - ((string-index line #\:) - (let lp () ;read until empty line - (let ((line (get-line-comp string-trim-both port))) - (if (string=? line "") - (get-line-comp string-trim-both port) - (lp))))) - (else line)))) - (let ((line (get-line-comp string-trim-both port))) - (cond ((eof-object? line) - (values "" (eof-object))) - ((string=? line "") - (get-delimited-base64 port)) - ((and (string-prefix? "-----BEGIN " line) - (string-suffix? "-----" line)) - (let* ((type (substring line 11 (- (string-length line) 5))) - (endline (string-append "-----END " type "-----"))) - (let-values (((outp extract) (open-bytevector-output-port))) - (let lp ((line (get-first-data-line port))) - (cond ((eof-object? line) - (error 'get-delimited-base64 - "unexpected end of file")) - ((string-prefix? "-" line) - (unless (string=? line endline) - (error 'get-delimited-base64 - "bad end delimiter" type line)) - (values type (extract))) - (else - (unless (and (= (string-length line) 5) - (string-prefix? "=" line)) ;Skip Radix-64 checksum - (base64-decode line base64-alphabet outp)) - (lp (get-line-comp string-trim-both port)))))))) - (else ;skip garbage (like in openssl x509 -in foo -text output). - (get-delimited-base64 port))))) +;; Reads the common -----BEGIN/END type----- delimited format from +;; the given port. Returns two values: a string with the type and a +;; bytevector containing the base64 decoded data. The second value +;; is the eof object if there is an eof before the BEGIN delimiter. +(define get-delimited-base64 + (case-lambda + ((port) + (get-delimited-base64 port #t)) + ((port strict) + (define (get-first-data-line port) + ;; Some MIME data has header fields in the same format as mail + ;; or http. These are ignored. + (let ((line (get-line-comp string-trim-both port))) + (cond ((eof-object? line) line) + ((string-index line #\:) + (let lp () ;read until empty line + (let ((line (get-line-comp string-trim-both port))) + (if (string=? line "") + (get-line-comp string-trim-both port) + (lp))))) + (else line)))) + (let ((line (get-line-comp string-trim-both port))) + (cond ((eof-object? line) + (values "" (eof-object))) + ((string=? line "") + (get-delimited-base64 port)) + ((and (string-prefix? "-----BEGIN " line) + (string-suffix? "-----" line)) + (let* ((type (substring line 11 (- (string-length line) 5))) + (endline (string-append "-----END " type "-----"))) + (let-values ([(outp extract) (open-bytevector-output-port)]) + (let lp ((previous "") (line (get-first-data-line port))) + (cond ((eof-object? line) + (error 'get-delimited-base64 + "unexpected end of file")) + ((string-prefix? "-" line) + (unless (string=? line endline) + (error 'get-delimited-base64 + "bad end delimiter" type line)) + (values type (extract))) + ((and (= (string-length line) 5) + (string-prefix? "=" line)) + ;; Skip Radix-64 checksum + (lp previous (get-line-comp string-trim-both port))) + ((not (fxzero? (fxmod (fx+ (string-length previous) + (string-length line)) + 4))) + ;; OpenSSH outputs lines with a bad length + (lp (string-append previous line) + (get-line-comp string-trim-both port))) + (else + (base64-decode (string-append previous line) base64-alphabet outp) + (lp "" (get-line-comp string-trim-both port)))))))) + (else ;skip garbage (like in openssl x509 -in foo -text output). + (get-delimited-base64 port))))))) (define put-delimited-base64 (case-lambda diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/guile-gcrypt/gcrypt/hash.scm new/guile-gcrypt/gcrypt/hash.scm --- old/guile-gcrypt/gcrypt/hash.scm 2020-05-23 12:23:29.000000000 +0200 +++ new/guile-gcrypt/gcrypt/hash.scm 2022-12-01 15:01:20.000000000 +0100 @@ -1,5 +1,5 @@ ;;; guile-gcrypt --- crypto tooling for guile -;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2019, 2020 Ludovic Courtès <l...@gnu.org> +;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2019, 2020, 2022 Ludovic Courtès <l...@gnu.org> ;;; Copyright © 2019 Mathieu Othacehe <m.othac...@gmail.com> ;;; ;;; This file is part of guile-gcrypt. @@ -79,7 +79,7 @@ "gcry_md_get_algo_dlen" (list int))) -;; 'GCRY_MD_' values as of Libgcrypt 1.8.3. +;; 'GCRY_MD_' values as of Libgcrypt 1.8.8. (define-hash-algorithms hash-algorithm lookup-hash-algorithm hash-algorithm-name hash-size @@ -119,7 +119,10 @@ (blake2s-256 322 32) (blake2s-224 323 28) (blake2s-160 324 20) - (blake2s-128 325 16)) + (blake2s-128 325 16) + (sm3 326 32) + (sha512-256 327 32) + (sha512-224 328 28)) (define bytevector-hash diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/guile-gcrypt/gcrypt/mac.scm new/guile-gcrypt/gcrypt/mac.scm --- old/guile-gcrypt/gcrypt/mac.scm 2020-05-23 12:23:29.000000000 +0200 +++ new/guile-gcrypt/gcrypt/mac.scm 2022-12-01 15:01:20.000000000 +0100 @@ -1,7 +1,7 @@ ;;; guile-gcrypt --- crypto tooling for guile ;;; Copyright © 2016 Christopher Allan Webber <cweb...@dustycloud.org> ;;; Copyright © 2019 Mathieu Othacehe <m.othac...@gmail.com> -;;; Copyright © 2019, 2020 Ludovic Courtès <l...@gnu.org> +;;; Copyright © 2019, 2020, 2022 Ludovic Courtès <l...@gnu.org> ;;; ;;; This file is part of guile-gcrypt. ;;; @@ -87,6 +87,18 @@ (hmac-sha3-256 116 32) (hmac-sha3-384 117 48) (hmac-sha3-512 118 64) + (hmac-gostr3411-cp 119 32) + (hmac-blake2b-512 120 64) + (hmac-blake2b-384 121 48) + (hmac-blake2b-256 122 32) + (hmac-blake2b-160 123 20) + (hmac-blake2s-256 124 32) + (hmac-blake2s-224 125 28) + (hmac-blake2s-160 126 20) + (hmac-blake2s-128 127 16) + (hmac-sm3 128 32) + (hmac-sha512-256 129 32) + (hmac-sha512-224 130 28) (cmac-aes 201 16) (cmac-3des 202 8) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/guile-gcrypt/guile-gcrypt.texi new/guile-gcrypt/guile-gcrypt.texi --- old/guile-gcrypt/guile-gcrypt.texi 2020-05-23 12:23:29.000000000 +0200 +++ new/guile-gcrypt/guile-gcrypt.texi 2022-12-01 15:01:20.000000000 +0100 @@ -10,7 +10,7 @@ @include version.texi @copying -Copyright @copyright{} 2018, 2019, 2020 Ludovic Courtès@* +Copyright @copyright{} 2018, 2019, 2020, 2021, 2022 Ludovic Courtès@* Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or @@ -194,8 +194,8 @@ the data written to the output port. @end deffn -@deffn {Scheme Procedure} port-hash @var{algorithm} -@deffnx {Scheme Procedure} port-sha256 +@deffn {Scheme Procedure} port-hash @var{algorithm} @var{port} +@deffnx {Scheme Procedure} port-sha256 @var{port} Return the @var{algorithm} hash (a bytevector) of all the data drained from @var{port}. @end deffn @@ -339,6 +339,50 @@ @code{find-sexp-token}, which accesses the canonical sexp directly, in search for the @code{public-key} symbol. +Those canonical sexps are the basic way to communicate information to +public-key crytography routines. The following procedures, for example, +are available to make and verify cryptographic signatures. + +@deffn {Scheme Procedure} bytevector->hash-data @var{bv} @ + [@var{hash-algo} "sha256"] [#:key-type 'ecc] +Given @var{bv}, a bytevector containing a hash of type @var{hash-algo}, +return an s-expression suitable for use as the @var{data} argument for +@code{sign} (see below). @var{key-type} must be a symbol: @code{'dsa}, +@code{'ecc}, or @code{'rsa}. +@end deffn + +@deffn {Scheme Procedure} sign @var{data} @var{secret-key} +Sign @var{data}, a canonical s-expression representing a suitable hash, +with @var{secret-key} (a canonical s-expression whose car is +@code{private-key}.) Note that @var{data} must be a @code{data} +s-expression, as returned by @code{bytevector->hash-data} +(@pxref{Cryptographic Functions,,, gcrypt, The Libgcrypt Libgcrypt}). +@end deffn + +@deffn {Scheme Procedure} verify @var{signature} @var{data} @var{public-key} +Verify that @var{signature} is a signature of @var{data} with +@var{public-key}, all of which are gcrypt s-expressions; return +@code{#t} if the verification was successful, @code{#f} otherwise. +Raise an error if, for example, one of the given s-expressions is +invalid. +@end deffn + +As an example, assuming @var{pair} is bound to the canonical sexp +representation of a key pair (as returned by @code{generate-key}), the +following snippet signs a string and verifies its signature: + +@lisp +(let* ((secret (find-sexp-token pair 'private-key)) + (public (find-sexp-token pair 'public-key)) + (data (bytevector->hash-data + (sha256 (string->utf8 "Hello, world.")) + #:key-type (key-type public))) + (sig (sign data secret))) + (verify sig data public)) + +@result{} #t +@end lisp + @xref{Used S-expressions,,, gcrypt, The Libgcrypt Library}, for more information on the canonical sexps consumed and produced by public-key cryptography functions. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/guile-gcrypt/tests/base64.scm new/guile-gcrypt/tests/base64.scm --- old/guile-gcrypt/tests/base64.scm 2020-05-23 12:23:29.000000000 +0200 +++ new/guile-gcrypt/tests/base64.scm 2022-12-01 15:01:20.000000000 +0100 @@ -29,10 +29,22 @@ (define (string->base64 str) (base64-encode (string->utf8 str))) +(define (base64->string base64) + (utf8->string (base64-decode base64))) + +(define (string->base64-padding str padding) + (let ((bv (string->utf8 str))) + (base64-encode bv 0 (bytevector-length bv) #f (not padding)))) + +(define (base64->string-padding base64 padding) + (utf8->string (base64-decode base64 base64url-alphabet #f #f padding))) + ;;; Test vectors from <https://tools.ietf.org/rfc/rfc4648.txt>. (test-begin "base64") +;; Encoding + (test-equal "empty string" (string->base64 "") "") @@ -61,4 +73,50 @@ (string->base64 "foobar") "Zm9vYmFy") +(test-equal "foob (no padding)" + (string->base64-padding "foob" #f) + "Zm9vYg") + +(test-equal "foob (padding)" + (string->base64-padding "foob" #t) + "Zm9vYg==") + +;; Decoding + +(test-equal "empty string" + (base64->string "") + "") + +(test-equal "f" + (base64->string "Zg==") + "f") + +(test-equal "fo" + (base64->string "Zm8=") + "fo") + +(test-equal "foo" + (base64->string "Zm9v") + "foo") + +(test-equal "foob" + (base64->string "Zm9vYg==") + "foob") + +(test-equal "fooba" + (base64->string "Zm9vYmE=") + "fooba") + +(test-equal "foobar" + (base64->string "Zm9vYmFy") + "foobar") + +(test-equal "foob (no padding)" + (base64->string-padding "Zm9vYg" #f) + "foob") + +(test-equal "foob (padding)" + (base64->string-padding "Zm9vYg==" #t) + "foob") + (test-end "base64")