// This file is dual-licensed. Choose whichever licence you want from // the two licences listed below. // // The first licence is a regular 2-clause BSD licence. The second licence // is the CC-0 from Creative Commons. It is intended to release Monocypher // to the public domain. The BSD licence serves as a fallback option. // // SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0 // // ------------------------------------------------------------------------ // // Copyright (c) 2017-2019, 2023 Loup Vaillant // All rights reserved. // // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the // distribution. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // ------------------------------------------------------------------------ // // Written in 2017-2019, 2023 by Loup Vaillant // // To the extent possible under law, the author(s) have dedicated all copyright // and related neighboring rights to this software to the public domain // worldwide. This software is distributed without any warranty. // // You should have received a copy of the CC0 Public Domain Dedication along // with this software. If not, see // #include "utils.h" #include #include #include u32 load32_le(const u8 s[4]) { return ((u32)s[0] << 0) | ((u32)s[1] << 8) | ((u32)s[2] << 16) | ((u32)s[3] << 24); } u64 load64_le(const u8 s[8]) { return load32_le(s) | ((u64)load32_le(s+4) << 32); } // Must be seeded with a nonzero value. // Accessible from the outside so we can modify it u64 random_state = 12345; // Pseudo-random 64 bit number, based on xorshift* u64 rand64(void) { random_state ^= random_state >> 12; random_state ^= random_state << 25; random_state ^= random_state >> 27; return random_state * 0x2545F4914F6CDD1D; // magic constant } void p_random(u8 *stream, size_t size) { FOR (i, 0, size) { stream[i] = (u8)rand64(); } } void* alloc(size_t size) { if (size == 0) { // Some systems refuse to allocate zero bytes. // So we don't. Instead, we just return a non-sensical pointer. // It shouldn't be dereferenced anyway. return NULL; } void *buf = malloc(size); ASSERT(buf != NULL); return buf; } static int to_num(char c) { return c >= '0' && c <= '9' ? c - '0' : c >= 'a' && c <= 'f' ? c - 'a' + 10 : c - 'A' + 10; } static vector vector_of_string(const char *s) { vector v; v.size = strlen(s) / 2; v.buf = v.size == 0 ? 0 : (u8*)alloc(v.size); FOR (i, 0, v.size) { int msb = to_num(*s); s++; int lsb = to_num(*s); s++; v.buf[i] = (u8)(msb * 16 + lsb); } return v; } vector next_input(vector_reader *reader) { ASSERT(reader->size > 0); ASSERT(reader->nb_inputs < 10); const char *next = *(reader->next); vector *input = reader->inputs + reader->nb_inputs; reader->next++; reader->size--; *input = vector_of_string(next); reader->nb_inputs++; return *input; } vector next_output(vector_reader *reader) { ASSERT(reader->size > 0); ASSERT(reader->nb_inputs < 10); const char *next = *(reader->next); reader->next++; reader->size--; reader->expected = vector_of_string(next); reader->out.size = reader->expected.size; reader->out.buf = (u8*)alloc(reader->out.size); return reader->out; } int vector_test(void (*f)(vector_reader*), const char *name, size_t nb_vectors, const char *vectors[]) { int status = 0; printf("\t%s\n", name); vector_reader in; in.size = nb_vectors; in.next = vectors; while (in.size > 0) { in.nb_inputs = 0; f(&in); if (in.expected.size != 0) { status |= memcmp(in.out.buf, in.expected.buf, in.expected.size); } FOR (i, 0, in.nb_inputs) { free(in.inputs[i].buf); } free(in.out.buf); free(in.expected.buf); } return status; }