gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnunet-scheme] 03/324: Define (de-)ASCIIification procedures for hash c


From: gnunet
Subject: [gnunet-scheme] 03/324: Define (de-)ASCIIification procedures for hash codes
Date: Tue, 21 Sep 2021 13:20:43 +0200

This is an automated email from the git hooks/post-receive script.

maxime-devos pushed a commit to branch master
in repository gnunet-scheme.

commit 6be6aca1f4f656af78a06103d9cff6ec69b56c6d
Author: Maxime Devos <maximedevos@telenet.be>
AuthorDate: Mon Nov 2 19:23:57 2020 +0100

    Define (de-)ASCIIification procedures for hash codes
---
 gnu/gnunet/data-string.scm    | 154 ++++++++++++++++++++++++++++++++++++++++++
 gnu/gnunet/hashcode-ascii.scm |  53 +++++++++++++++
 2 files changed, 207 insertions(+)

diff --git a/gnu/gnunet/data-string.scm b/gnu/gnunet/data-string.scm
new file mode 100644
index 0000000..5d6ae0e
--- /dev/null
+++ b/gnu/gnunet/data-string.scm
@@ -0,0 +1,154 @@
+;;   This file is part of scheme-GNUnet, a partial Scheme port of GNUnet.
+;;   Copyright (C) 2005--207 GNUnet e.V.
+;;   Copyright (C) 2020 Maxime Devos <maxime.devos@student.kuleuven.be>
+;;
+;;   GNUnet is free software: you can redistribute it and/or modify it
+;;   under the terms of the GNU Affero General Public License as published
+;;   by the Free Software Foundation, either version 3 of the License,
+;;   or (at your option) any later version.
+;;
+;;   GNUnet is distributed in the hope that it will be useful, but
+;;   WITHOUT ANY WARRANTY; without even the implied warranty of
+;;   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+;;   Affero General Public License for more details.
+;;
+;;   You should have received a copy of the GNU Affero General Public License
+;;   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+;;
+;;   SPDX-License-Identifier: AGPL-3.0-or-later
+;;
+;;   As a special exception to the GNU Affero General Public License,
+;;   the file may be relicensed under any license used for
+;;   most source code of GNUnet 0.13.1, or later versions, as published by
+;;   GNUnet e.V.
+
+;; Extracted from src/util/strings.c by Nils Durner and Christian Grothoff.
+
+;; Deviations from upstream:
+;;   * Alternative characters aren't recognised.
+;;     (The alternative encodings aren't generated by GNUnet anyway)
+;;     TODO: perhaps reject alternate encodings (e.g. "00" and "01" both
+;;     decode to 0 currently)
+
+(library (gnu gnunet data-string (1 1))
+  (export data->string string->data)
+  (import (rnrs base)
+          (rnrs control)
+         (rnrs bytevectors)
+         (rnrs arithmetic bitwise))
+
+  (define charset "0123456789ABCDEFGHJKMNPQRSTVWXYZ")
+
+  (define data->string
+    (case-lambda
+      "Convert binary data to ASCII encoding using Crockford Base32 encoding.
+
+@var{bv}: data to encode
+@var{offset}: start position of data to encode
+@var{size}: length of data to encode, in octets"
+      ((bv) (data->string bv 0 (bytevector-length bv)))
+      ((bv offset size)
+       (let loop ((vbit 0) (rpos offset) (bits 0) (accumulated '()))
+         (if (or (< (- rpos offset) size) (> vbit 0))
+             (begin
+               (when (and (< (- rpos offset) size) (< vbit 5))
+                (set! bits (bitwise-ior (bitwise-arithmetic-shift-left bits 8)
+                                        (bytevector-u8-ref bv rpos)))
+                (set! rpos (+ 1 rpos))
+                (set! vbit (+ vbit 8)))
+               (when (< vbit 5)
+                (set! bits (bitwise-arithmetic-shift-left bits (- 5 vbit)))
+                (assert (= vbit (mod (* 8 size) 5)))
+                (set! vbit 5))
+               (loop (- vbit 5) rpos bits
+                    (cons (string-ref charset
+                                      (bitwise-and
+                                       (bitwise-arithmetic-shift-right
+                                        bits (- vbit 5)) 31))
+                          accumulated)))
+             (begin (assert (= 0 vbit))
+                    (apply string (reverse accumulated))))))))
+
+  (define (get-value ch)
+    "Get the decoded value corresponding to a character according to Crockford
+Base32 encoding."
+    (cond ((and (char<=? #\0 ch) (char<=? ch #\9))
+          (- (char->integer ch) (char->integer #\0)))
+         ((and (char<=? #\A ch) (char<=? ch #\H))
+          (- (char->integer ch) (char->integer #\A) -10))
+         ((and (char<=? #\J ch) (char<=? ch #\K))
+          (- (char->integer ch) (char->integer #\J) -18))
+         ((and (char<=? #\M ch) (char<=? ch #\N))
+          (- (char->integer ch) (char->integer #\M) -20))
+         ((and (char<=? #\P ch) (char<=? ch #\T))
+          (- (char->integer ch) (char->integer #\P) -22))
+         ((and (char<=? #\V ch) (char<=? ch #\Z))
+          (- (char->integer ch) (char->integer #\V) -27))
+         (else #f)))
+
+  (define string->data
+    (lambda (enc out-size)
+      "Convert Crockford Base32hex encoding back to data
+
+Return the data as a bytevector on success, or return #f
+if result has the wrong encoding.
+@var{out-size} must exactly match the size of the data before it was encoded.
+
+@var{enc} the encoding
+@var{out-size} size of output buffer"
+      (let ((rpos (string-length enc))
+           (bits #f)
+           (vbit #f)
+           (ret #f)
+           (shift #f)
+           (encoded-len (* 8 out-size))
+           (uout (make-bytevector out-size)))
+       (if (= 0 (string-length enc))
+           (if (= 0 out-size)
+               #vu8()
+               #f)
+           (begin
+             (if (< 0 (mod encoded-len 5))
+                 (begin ; padding!
+                   (set! vbit (mod encoded-len 5))
+                   (set! shift (- 5 vbit))
+                   (set! rpos (- rpos 1))
+                   (set! ret (get-value (string-ref enc rpos)))
+                   (set! bits (bitwise-arithmetic-shift-right ret shift)))
+                 (begin
+                   (set! vbit 5)
+                   (set! shift 0)
+                   (set! rpos (- rpos 1))
+                   (set! ret (get-value (string-ref enc rpos)))
+                   (set! bits ret)))
+             (cond ((not (= (/ (+ encoded-len shift) 5)
+                            (string-length enc)))
+                    #f)
+                   ((not ret)
+                    #f)
+                   (else
+                    (let loop ((wpos out-size))
+                      (if (> wpos 0)
+                          (begin
+                            (assert (not (= 0 rpos)))
+                            (set! rpos (- rpos 1))
+                            (set! ret (get-value (string-ref enc rpos)))
+                            (set! bits (bitwise-ior
+                                        (bitwise-arithmetic-shift-left
+                                         ret vbit)
+                                        bits))
+                            (and ret
+                                 (begin
+                                   (set! vbit (+ vbit 5))
+                                   (when (>= vbit 8)
+                                     (set! wpos (- wpos 1))
+                                     (bytevector-u8-set! uout wpos
+                                                         (bitwise-and bits
+                                                                      255))
+                                     (set! bits
+                                       (bitwise-arithmetic-shift-right bits 8))
+                                     (set! vbit (- vbit 8)))
+                                   (loop wpos))))
+                          (if (and (= 0 rpos) (= 0 vbit))
+                              uout
+                              #f)))))))))))
diff --git a/gnu/gnunet/hashcode-ascii.scm b/gnu/gnunet/hashcode-ascii.scm
new file mode 100644
index 0000000..6345816
--- /dev/null
+++ b/gnu/gnunet/hashcode-ascii.scm
@@ -0,0 +1,53 @@
+;;   This file is part of scheme-GNUnet, a partial Scheme port of GNUnet.
+;;   Copyright (C) 2001--2013 GNUnet e.V.
+;;   Copyright (C) 2020 Maxime Devos <maxime.devos@student.kuleuven.be>
+;;
+;;   GNUnet is free software: you can redistribute it and/or modify it
+;;   under the terms of the GNU Affero General Public License as published
+;;   by the Free Software Foundation, either version 3 of the License,
+;;   or (at your option) any later version.
+;;
+;;   GNUnet is distributed in the hope that it will be useful, but
+;;   WITHOUT ANY WARRANTY; without even the implied warranty of
+;;   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+;;   Affero General Public License for more details.
+;;
+;;   You should have received a copy of the GNU Affero General Public License
+;;   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+;;
+;;   SPDX-License-Identifier: AGPL-3.0-or-later
+;;
+;;   As a special exception to the GNU Affero General Public License,
+;;   the file may be relicensed under any license used for
+;;   most source code of GNUnet 0.13.1, or later versions, as published by
+;;   GNUnet e.V.
+
+;; Extracted from src/util/crypto_hash.c by Christian Grothoff
+
+(library (gnu gnunet hashcode-ascii (1 1))
+  (export hashcode->ascii ascii->hashcode
+          #; hashcode-ascii-length)
+  (import (gnu gnunet hashcode)
+          (gnu gnunet data-string)
+         (rnrs base))
+
+  ;; In upstream, this is 104 for the \0 terminator
+  #;(define hashcode-ascii-length 103)
+
+  (define (hashcode->ascii hashcode)
+    "Convert a <hashcode> to ASCII encoding.  The ASCII encoding is rather
+GNUnet specific.  It was chosen such that it only uses characters
+in [0-9A-V], can be produced without complex arithmetics and uses a
+small number of characters.  The GNUnet encoding uses 103
+characters.
+
+@var{block} the hash code"
+    (data->string (hashcode->bv hashcode)))
+
+  (define (ascii->hashcode ascii)
+    "Convert ASCII encoding back to hash code.
+
+@var{ascii} the encoding
+Return @lisp{#f} in case of an encoding error."
+    (let ((bv (string->data ascii hashcode-u8-length)))
+      (and bv (bv->hashcode bv)))))

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]