/*
  This file is part of paivana tests.
  Copyright (C) 2026 Taler Systems SA

  Paivana 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, or (at your option) any later version.

  Paivana 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 Paivana; see the file COPYING.  If not,
  write to the Free Software Foundation, Inc., 51 Franklin
  Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

/**
 * @file base64url_vectors.c
 * @brief Print base64url test vectors as the daemon produces them, for
 *        `test_base64url.sh' to check the paywall's JavaScript against.
 *
 *        The paivana ID is `<expiration>-<base64url(sha256(...))>', and
 *        the browser recomputes it from the same inputs to recognise
 *        the payment it just made.  Nothing forces the two encoders to
 *        agree, and they have already disagreed twice: once on the
 *        decode side, where the daemon emitted the RFC 4648 section 5
 *        alphabet and the browser fed it to atob(), which only knows
 *        section 4; and once on the encode side, where the browser
 *        used a method older engines do not have.  Both broke the
 *        payment path and neither was visible from either side alone.
 *
 *        Output is one vector per line, `<hex-input> <expected>', with
 *        an empty input written as `-'.
 */
#include "platform.h"
#include <gnunet/gnunet_util_lib.h>


/**
 * Print one vector for the @a len bytes at @a buf.
 */
static void
emit (const unsigned char *buf,
      size_t len)
{
  char *out = NULL;
  size_t n;

  if (0 == len)
    printf ("-");
  for (size_t i = 0; i < len; i++)
    printf ("%02x", buf[i]);
  n = GNUNET_STRINGS_base64url_encode (buf,
                                       len,
                                       &out);
  printf (" %.*s\n",
          (int) n,
          out);
  GNUNET_free (out);
}


int
main (int argc,
      char **argv)
{
  unsigned char buf[96] = { 0 };

  (void) argc;
  (void) argv;
  /* Every length from 0 to 96, which crosses the three-byte group
     boundary in all its phases and so exercises both amounts of
     padding as well as none. */
  for (size_t len = 0; len <= sizeof (buf); len++)
  {
    for (size_t i = 0; i < len; i++)
      buf[i] = (unsigned char) ((i * 37 + len * 11) & 0xFF);
    emit (buf,
          len);
  }
  /* Every single byte value, so no corner of the alphabet is missed --
     '-' and '_' are only reachable from particular high bit patterns,
     and they are exactly the two characters the section 4 alphabet
     spells differently. */
  for (unsigned int v = 0; v < 256; v++)
  {
    unsigned char b = (unsigned char) v;

    emit (&b,
          1);
  }
  /* And a 32-byte block, which is the size that actually occurs: the
     ID is a SHA-256 digest. */
  for (unsigned int round = 0; round < 16; round++)
  {
    for (size_t i = 0; i < 32; i++)
      buf[i] = (unsigned char) ((i * 101 + round * 251) & 0xFF);
    emit (buf,
          32);
  }
  return 0;
}


/* end of base64url_vectors.c */
