Add sha512* from Zknh, and associated Supercop test

This commit is contained in:
Romain Dolbeau 2020-11-11 12:29:17 -05:00
parent 45cd343b25
commit b49ce75e1f
19 changed files with 1147 additions and 11 deletions

View file

@ -10,31 +10,64 @@ object CryptoZknhPlugin {
object CryptoZknhCtrlsha256sumEnum extends SpinalEnum(binarySequential) {
val CTRL_sha256sum0, CTRL_sha256sum1 = newElement()
}
object CryptoZknhCtrlsha512sigEnum extends SpinalEnum(binarySequential) {
val CTRL_sha512sig0h, CTRL_sha512sig0l, CTRL_sha512sig1h, CTRL_sha512sig1l = newElement()
}
object CryptoZknhCtrlsha512sumEnum extends SpinalEnum(binarySequential) {
val CTRL_sha512sum0r, CTRL_sha512sum1r = newElement()
}
object CryptoZknhCtrlEnum extends SpinalEnum(binarySequential) {
val CTRL_sha256sig, CTRL_sha256sum = newElement()
val CTRL_sha256sig, CTRL_sha256sum, CTRL_sha512sig, CTRL_sha512sum = newElement()
}
object CryptoZknhCtrlsha256sig extends Stageable(CryptoZknhCtrlsha256sigEnum())
object CryptoZknhCtrlsha256sum extends Stageable(CryptoZknhCtrlsha256sumEnum())
object CryptoZknhCtrlsha512sig extends Stageable(CryptoZknhCtrlsha512sigEnum())
object CryptoZknhCtrlsha512sum extends Stageable(CryptoZknhCtrlsha512sumEnum())
object CryptoZknhCtrl extends Stageable(CryptoZknhCtrlEnum())
// Prologue
def fun_sha256sig0(rs1:Bits) : Bits = {
def fun_sha256sig0(rs1:Bits) : Bits = {
val r = rs1.rotateRight(7) ^ rs1.rotateRight(18) ^ (rs1 |>> 3)
r // return value
}
def fun_sha256sig1(rs1:Bits) : Bits = {
def fun_sha256sig1(rs1:Bits) : Bits = {
val r = rs1.rotateRight(17) ^ rs1.rotateRight(19) ^ (rs1 |>> 10)
r // return value
}
def fun_sha256sum0(rs1:Bits) : Bits = {
def fun_sha256sum0(rs1:Bits) : Bits = {
val r = rs1.rotateRight(2) ^ rs1.rotateRight(13) ^ rs1.rotateRight(22)
r // return value
}
def fun_sha256sum1(rs1:Bits) : Bits = {
def fun_sha256sum1(rs1:Bits) : Bits = {
val r = rs1.rotateRight(6) ^ rs1.rotateRight(11) ^ rs1.rotateRight(25)
r // return value
}
def fun_sha512sig0l(rs1:Bits, rs2:Bits) : Bits = {
val r = (rs1 |>> 1) ^ (rs1 |>> 7) ^ (rs1 |>> 8) ^ (rs2 |<< 31) ^ (rs2 |<< 25) ^ (rs2 |<< 24)
r // return value
}
def fun_sha512sig0h(rs1:Bits, rs2:Bits) : Bits = {
val r = (rs1 |>> 1) ^ (rs1 |>> 7) ^ (rs1 |>> 8) ^ (rs2 |<< 31) ^ (rs2 |<< 24)
r // return value
}
def fun_sha512sig1l(rs1:Bits, rs2:Bits) : Bits = {
val r = (rs1 |<< 3) ^ (rs1 |>> 6) ^ (rs1 |>> 19) ^ (rs2 |>> 29) ^ (rs2 |<< 26) ^ (rs2 |<< 13)
r // return value
}
def fun_sha512sig1h(rs1:Bits, rs2:Bits) : Bits = {
val r = (rs1 |<< 3) ^ (rs1 |>> 6) ^ (rs1 |>> 19) ^ (rs2 |>> 29) ^ (rs2 |<< 13)
r // return value
}
def fun_sha512sum0r(rs1:Bits, rs2:Bits) : Bits = {
val r = (rs1 |<< 25) ^ (rs1 |<< 30) ^ (rs1 |>> 28) ^ (rs2 |>> 7) ^ (rs2 |>> 2) ^ (rs2 |<< 4)
r // return value
}
def fun_sha512sum1r(rs1:Bits, rs2:Bits) : Bits = {
val r = (rs1 |<< 23) ^ (rs1 |>> 14) ^ (rs1 |>> 18) ^ (rs2 |>> 9) ^ (rs2 |<< 18) ^ (rs2 |<< 14)
r // return value
}
// End prologue
} // object Plugin
class CryptoZknhPlugin extends Plugin[VexRiscv] {
@ -73,13 +106,25 @@ class CryptoZknhPlugin extends Plugin[VexRiscv] {
def sha256sig1_KEY = M"000011100001-----111-----0101011"
def sha256sum0_KEY = M"000011100010-----111-----0101011"
def sha256sum1_KEY = M"000011100011-----111-----0101011"
def sha512sig0l_KEY = M"0001000----------111-----0101011"
def sha512sig0h_KEY = M"0001001----------111-----0101011"
def sha512sig1l_KEY = M"0001010----------111-----0101011"
def sha512sig1h_KEY = M"0001011----------111-----0101011"
def sha512sum0r_KEY = M"0001100----------111-----0101011"
def sha512sum1r_KEY = M"0001101----------111-----0101011"
val decoderService = pipeline.service(classOf[DecoderService])
decoderService.addDefault(IS_CryptoZknh, False)
decoderService.add(List(
sha256sig0_KEY -> (unaryActions ++ List(CryptoZknhCtrl -> CryptoZknhCtrlEnum.CTRL_sha256sig, CryptoZknhCtrlsha256sig -> CryptoZknhCtrlsha256sigEnum.CTRL_sha256sig0)),
sha256sig1_KEY -> (unaryActions ++ List(CryptoZknhCtrl -> CryptoZknhCtrlEnum.CTRL_sha256sig, CryptoZknhCtrlsha256sig -> CryptoZknhCtrlsha256sigEnum.CTRL_sha256sig1)),
sha256sum0_KEY -> (unaryActions ++ List(CryptoZknhCtrl -> CryptoZknhCtrlEnum.CTRL_sha256sum, CryptoZknhCtrlsha256sum -> CryptoZknhCtrlsha256sumEnum.CTRL_sha256sum0)),
sha256sum1_KEY -> (unaryActions ++ List(CryptoZknhCtrl -> CryptoZknhCtrlEnum.CTRL_sha256sum, CryptoZknhCtrlsha256sum -> CryptoZknhCtrlsha256sumEnum.CTRL_sha256sum1))
sha256sum1_KEY -> (unaryActions ++ List(CryptoZknhCtrl -> CryptoZknhCtrlEnum.CTRL_sha256sum, CryptoZknhCtrlsha256sum -> CryptoZknhCtrlsha256sumEnum.CTRL_sha256sum1)),
sha512sig0l_KEY -> (binaryActions ++ List(CryptoZknhCtrl -> CryptoZknhCtrlEnum.CTRL_sha512sig, CryptoZknhCtrlsha512sig -> CryptoZknhCtrlsha512sigEnum.CTRL_sha512sig0l)),
sha512sig0h_KEY -> (binaryActions ++ List(CryptoZknhCtrl -> CryptoZknhCtrlEnum.CTRL_sha512sig, CryptoZknhCtrlsha512sig -> CryptoZknhCtrlsha512sigEnum.CTRL_sha512sig0h)),
sha512sig1l_KEY -> (binaryActions ++ List(CryptoZknhCtrl -> CryptoZknhCtrlEnum.CTRL_sha512sig, CryptoZknhCtrlsha512sig -> CryptoZknhCtrlsha512sigEnum.CTRL_sha512sig1l)),
sha512sig1h_KEY -> (binaryActions ++ List(CryptoZknhCtrl -> CryptoZknhCtrlEnum.CTRL_sha512sig, CryptoZknhCtrlsha512sig -> CryptoZknhCtrlsha512sigEnum.CTRL_sha512sig1h)),
sha512sum0r_KEY -> (binaryActions ++ List(CryptoZknhCtrl -> CryptoZknhCtrlEnum.CTRL_sha512sum, CryptoZknhCtrlsha512sum -> CryptoZknhCtrlsha512sumEnum.CTRL_sha512sum0r)),
sha512sum1r_KEY -> (binaryActions ++ List(CryptoZknhCtrl -> CryptoZknhCtrlEnum.CTRL_sha512sum, CryptoZknhCtrlsha512sum -> CryptoZknhCtrlsha512sumEnum.CTRL_sha512sum1r))
))
} // override def setup
override def build(pipeline: VexRiscv): Unit = {
@ -95,10 +140,22 @@ class CryptoZknhPlugin extends Plugin[VexRiscv] {
CryptoZknhCtrlsha256sumEnum.CTRL_sha256sum0 -> fun_sha256sum0(input(SRC1)),
CryptoZknhCtrlsha256sumEnum.CTRL_sha256sum1 -> fun_sha256sum1(input(SRC1))
) // mux sha256sum
val val_sha512sig = input(CryptoZknhCtrlsha512sig).mux(
CryptoZknhCtrlsha512sigEnum.CTRL_sha512sig0h -> fun_sha512sig0h(input(SRC1),input(SRC2)),
CryptoZknhCtrlsha512sigEnum.CTRL_sha512sig0l -> fun_sha512sig0l(input(SRC1),input(SRC2)),
CryptoZknhCtrlsha512sigEnum.CTRL_sha512sig1h -> fun_sha512sig1h(input(SRC1),input(SRC2)),
CryptoZknhCtrlsha512sigEnum.CTRL_sha512sig1l -> fun_sha512sig1l(input(SRC1),input(SRC2))
) // mux sha512sig
val val_sha512sum = input(CryptoZknhCtrlsha512sum).mux(
CryptoZknhCtrlsha512sumEnum.CTRL_sha512sum0r -> fun_sha512sum0r(input(SRC1),input(SRC2)),
CryptoZknhCtrlsha512sumEnum.CTRL_sha512sum1r -> fun_sha512sum1r(input(SRC1),input(SRC2))
) // mux sha512sum
when (input(IS_CryptoZknh)) {
execute.output(REGFILE_WRITE_DATA) := input(CryptoZknhCtrl).mux(
CryptoZknhCtrlEnum.CTRL_sha256sig -> val_sha256sig.asBits,
CryptoZknhCtrlEnum.CTRL_sha256sum -> val_sha256sum.asBits
CryptoZknhCtrlEnum.CTRL_sha256sum -> val_sha256sum.asBits,
CryptoZknhCtrlEnum.CTRL_sha512sig -> val_sha512sig.asBits,
CryptoZknhCtrlEnum.CTRL_sha512sum -> val_sha512sum.asBits
) // primary mux
} // when input is
} // execute plug newArea

View file

@ -25,21 +25,85 @@ S sha256sig1 "fun_sha256sig1(input(SRC1))"
S sha256sum0 "fun_sha256sum0(input(SRC1))"
S sha256sum1 "fun_sha256sum1(input(SRC1))"
//#define MATCH_SHA512SIG0L 0x1000702b
//#define MASK_SHA512SIG0L 0xfe00707f
//#define MATCH_SHA512SIG0H 0x1200702b
//#define MASK_SHA512SIG0H 0xfe00707f
//#define MATCH_SHA512SIG1L 0x1400702b
//#define MASK_SHA512SIG1L 0xfe00707f
//#define MATCH_SHA512SIG1H 0x1600702b
//#define MASK_SHA512SIG1H 0xfe00707f
//#define MATCH_SHA512SUM0R 0x1800702b
//#define MASK_SHA512SUM0R 0xfe00707f
//#define MATCH_SHA512SUM1R 0x1a00702b
//#define MASK_SHA512SUM1R 0xfe00707f
//{"sha512sig0l" , 0, INSN_CLASS_I, "d,s,t", MATCH_SHA512SIG0L, MASK_SHA512SIG0L, match_opcode, 0},
//{"sha512sig0h" , 0, INSN_CLASS_I, "d,s,t", MATCH_SHA512SIG0H, MASK_SHA512SIG0H, match_opcode, 0},
//{"sha512sig1l" , 0, INSN_CLASS_I, "d,s,t", MATCH_SHA512SIG1L, MASK_SHA512SIG1L, match_opcode, 0},
//{"sha512sig1h" , 0, INSN_CLASS_I, "d,s,t", MATCH_SHA512SIG1H, MASK_SHA512SIG1H, match_opcode, 0},
//{"sha512sum0r" , 0, INSN_CLASS_I, "d,s,t", MATCH_SHA512SUM0R, MASK_SHA512SUM0R, match_opcode, 0},
//{"sha512sum1r" , 0, INSN_CLASS_I, "d,s,t", MATCH_SHA512SUM1R, MASK_SHA512SUM1R, match_opcode, 0},
//0001000 rs2 rs1 111 rd 0101011 sha512sig0l
//0001001 rs2 rs1 111 rd 0101011 sha512sig0h
//0001010 rs2 rs1 111 rd 0101011 sha512sig1l
//0001011 rs2 rs1 111 rd 0101011 sha512sig1h
//0001100 rs2 rs1 111 rd 0101011 sha512sum0r
//0001101 rs2 rs1 111 rd 0101011 sha512sum1r
I sha512sig0l sha512sig0l 0001000----------111-----0101011 sha512sig Zknh
I sha512sig0h sha512sig0h 0001001----------111-----0101011 sha512sig Zknh
I sha512sig1l sha512sig1l 0001010----------111-----0101011 sha512sig Zknh
I sha512sig1h sha512sig1h 0001011----------111-----0101011 sha512sig Zknh
I sha512sum0r sha512sum0r 0001100----------111-----0101011 sha512sum Zknh
I sha512sum1r sha512sum1r 0001101----------111-----0101011 sha512sum Zknh
S sha512sig0l "fun_sha512sig0l(input(SRC1),input(SRC2))"
S sha512sig0h "fun_sha512sig0h(input(SRC1),input(SRC2))"
S sha512sig1l "fun_sha512sig1l(input(SRC1),input(SRC2))"
S sha512sig1h "fun_sha512sig1h(input(SRC1),input(SRC2))"
S sha512sum0r "fun_sha512sum0r(input(SRC1),input(SRC2))"
S sha512sum1r "fun_sha512sum1r(input(SRC1),input(SRC2))"
P """
def fun_sha256sig0(rs1:Bits) : Bits = {
def fun_sha256sig0(rs1:Bits) : Bits = {
val r = rs1.rotateRight(7) ^ rs1.rotateRight(18) ^ (rs1 |>> 3)
r // return value
}
def fun_sha256sig1(rs1:Bits) : Bits = {
def fun_sha256sig1(rs1:Bits) : Bits = {
val r = rs1.rotateRight(17) ^ rs1.rotateRight(19) ^ (rs1 |>> 10)
r // return value
}
def fun_sha256sum0(rs1:Bits) : Bits = {
def fun_sha256sum0(rs1:Bits) : Bits = {
val r = rs1.rotateRight(2) ^ rs1.rotateRight(13) ^ rs1.rotateRight(22)
r // return value
}
def fun_sha256sum1(rs1:Bits) : Bits = {
def fun_sha256sum1(rs1:Bits) : Bits = {
val r = rs1.rotateRight(6) ^ rs1.rotateRight(11) ^ rs1.rotateRight(25)
r // return value
}
def fun_sha512sig0l(rs1:Bits, rs2:Bits) : Bits = {
val r = (rs1 |>> 1) ^ (rs1 |>> 7) ^ (rs1 |>> 8) ^ (rs2 |<< 31) ^ (rs2 |<< 25) ^ (rs2 |<< 24)
r // return value
}
def fun_sha512sig0h(rs1:Bits, rs2:Bits) : Bits = {
val r = (rs1 |>> 1) ^ (rs1 |>> 7) ^ (rs1 |>> 8) ^ (rs2 |<< 31) ^ (rs2 |<< 24)
r // return value
}
def fun_sha512sig1l(rs1:Bits, rs2:Bits) : Bits = {
val r = (rs1 |<< 3) ^ (rs1 |>> 6) ^ (rs1 |>> 19) ^ (rs2 |>> 29) ^ (rs2 |<< 26) ^ (rs2 |<< 13)
r // return value
}
def fun_sha512sig1h(rs1:Bits, rs2:Bits) : Bits = {
val r = (rs1 |<< 3) ^ (rs1 |>> 6) ^ (rs1 |>> 19) ^ (rs2 |>> 29) ^ (rs2 |<< 13)
r // return value
}
def fun_sha512sum0r(rs1:Bits, rs2:Bits) : Bits = {
val r = (rs1 |<< 25) ^ (rs1 |<< 30) ^ (rs1 |>> 28) ^ (rs2 |>> 7) ^ (rs2 |>> 2) ^ (rs2 |<< 4)
r // return value
}
def fun_sha512sum1r(rs1:Bits, rs2:Bits) : Bits = {
val r = (rs1 |<< 23) ^ (rs1 |>> 14) ^ (rs1 |>> 18) ^ (rs2 |>> 9) ^ (rs2 |<< 18) ^ (rs2 |<< 14)
r // return value
}
"""

View file

@ -0,0 +1,47 @@
SRCs=blocks.c try-anything.c
OBJs=$(SRCs:.c=.o)
SCLIBS=cpucycles.o kernelrandombytes.o
COMPDIR=/home/dolbeau/LITEX/riscv64-unknown-elf-gcc-8.3.0-2019.08.0-x86_64-linux-ubuntu14
ALTCOMPDIR=/opt/riscv64b
CC=$(COMPDIR)/bin/riscv64-unknown-elf-gcc
ALTCC=$(ALTCOMPDIR)/bin/riscv64-unknown-elf-gcc
CC=$(ALTCC)
CXX=$(COMPDIR)/bin/riscv64-unknown-elf-g++
STRIP=$(COMPDIR)/bin/riscv64-unknown-elf-strip
NEWOPT=-march=rv32imab -mabi=ilp32 -I. -O3 -DRV32ZKNH #-fno-vectorize #-DUSE_EPI_CUSTOM
OPT=-march=rv32ima -mabi=ilp32 -I. -O3 #-fno-vectorize #-DUSE_EPI_CUSTOM
#NEWOPT=$(OPT)
all: sha512 sha512_small
clean:
rm -f $(OBJs) try.o try_small.o blocks.o sha512 sha512_small blocks.S
%.o: %.c
$(CC) $(NEWOPT) $< -c -o $@
try.o: try.c
$(CC) $(NEWOPT) $< -c -o $@
try_small.o: try.c
$(CC) $(NEWOPT) $< -c -o $@ -DSMALL
blocks.S: blocks.c
$(CC) $(NEWOPT) $< -S -o $@
blocks.o: blocks.S
$(CC) $(NEWOPT) $< -c -o $@
sha512: $(OBJs) blocks.o try.o $(SCLIBS)
$(CXX) $(OPT) $^ -o $@
sha512_small: $(OBJs) blocks.o try_small.o $(SCLIBS)
$(CXX) $(OPT) $^ -o $@
kernelrandombytes.o: random.cpp
$(CXX) $(OPT) $< -c -o $@
cpucycles.o: riscv.c
$(CC) $< -march=rv32ima -mabi=ilp32 -I. -O1 -c -o $@

View file

@ -0,0 +1,2 @@
#define CRYPTO_STATEBYTES 64
#define CRYPTO_BLOCKBYTES 128

View file

@ -0,0 +1,322 @@
#include "crypto_hashblocks.h"
typedef unsigned long long uint64;
#ifdef RV32ZKNH
typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;
#define ASM1MACRO(N, O) asm(".macro "#N" rd, rs1\n" \
".word ("#O" | (\\rd << 7) | (\\rs1 << 15))\n" \
".endm\n");
#define ASM2MACRO(N, O) asm(".macro "#N" rd, rs1, rs2\n" \
".word ("#O" | (\\rd << 7) | (\\rs1 << 15) | (\\rs2 << 20))\n" \
".endm\n");
asm("#define reg_zero 0\n");
asm("#define reg_ra 1\n");
asm("#define reg_sp 2\n");
asm("#define reg_gp 3\n");
asm("#define reg_tp 4\n");
asm("#define reg_t0 5\n");
asm("#define reg_t1 6\n");
asm("#define reg_t2 7\n");
asm("#define reg_s0 8\n");
asm("#define reg_s1 9\n");
asm("#define reg_a0 10\n");
asm("#define reg_a1 11\n");
asm("#define reg_a2 12\n");
asm("#define reg_a3 13\n");
asm("#define reg_a4 14\n");
asm("#define reg_a5 15\n");
asm("#define reg_a6 16\n");
asm("#define reg_a7 17\n");
asm("#define reg_s2 18\n");
asm("#define reg_s3 19\n");
asm("#define reg_s4 20\n");
asm("#define reg_s5 21\n");
asm("#define reg_s6 22\n");
asm("#define reg_s7 23\n");
asm("#define reg_s8 24\n");
asm("#define reg_s9 25\n");
asm("#define reg_s10 26\n");
asm("#define reg_s11 27\n");
asm("#define reg_t3 28\n");
asm("#define reg_t4 29\n");
asm("#define reg_t5 30\n");
asm("#define reg_t6 31\n");
#define FUN1(NAME, ASNAME) \
static inline uint32_t NAME(uint32_t rs1) { \
uint32_t r; \
asm (#ASNAME " reg_%0, reg_%1\n" \
: "=r" (r) \
: "r" (rs1)); \
return r; \
}
#define FUN2(NAME, ASNAME) \
static inline uint32_t NAME(uint32_t rs1, uint32_t rs2) { \
uint32_t r; \
asm (#ASNAME " reg_%0, reg_%1, reg_%2\n" \
: "=r" (r) \
: "r" (rs1), "r" (rs2)); \
return r; \
}
ASM2MACRO(SHA512SIG0L,0x1000702b)
ASM2MACRO(SHA512SIG0H,0x1200702b)
ASM2MACRO(SHA512SIG1L,0x1400702b)
ASM2MACRO(SHA512SIG1H,0x1600702b)
ASM2MACRO(SHA512SUM0R,0x1800702b)
ASM2MACRO(SHA512SUM1R,0x1a00702b)
FUN2(sha512sig0l, SHA512SIG0L)
FUN2(sha512sig0h, SHA512SIG0H)
FUN2(sha512sig1l, SHA512SIG1L)
FUN2(sha512sig1h, SHA512SIG1H)
FUN2(sha512sum0r, SHA512SUM0R)
FUN2(sha512sum1r, SHA512SUM1R)
#endif
static uint64 load_bigendian(const unsigned char *x)
{
return
(uint64) (x[7]) \
| (((uint64) (x[6])) << 8) \
| (((uint64) (x[5])) << 16) \
| (((uint64) (x[4])) << 24) \
| (((uint64) (x[3])) << 32) \
| (((uint64) (x[2])) << 40) \
| (((uint64) (x[1])) << 48) \
| (((uint64) (x[0])) << 56)
;
}
static void store_bigendian(unsigned char *x,uint64 u)
{
x[7] = u; u >>= 8;
x[6] = u; u >>= 8;
x[5] = u; u >>= 8;
x[4] = u; u >>= 8;
x[3] = u; u >>= 8;
x[2] = u; u >>= 8;
x[1] = u; u >>= 8;
x[0] = u;
}
#define SHR(x,c) ((x) >> (c))
#define ROTR(x,c) (((x) >> (c)) | ((x) << (64 - (c))))
#define Ch(x,y,z) ((x & y) ^ (~x & z))
#define Maj(x,y,z) ((x & y) ^ (x & z) ^ (y & z))
#ifndef RV32ZKNH
#define Sigma0(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
#define Sigma1(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
#define sigma0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x,7))
#define sigma1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x,6))
#else
#define Sigma0(x) (((uint64_t)sha512sum0r((uint32_t)(x>>32),(uint32_t)x))<<32 | ((uint64_t)sha512sum0r((uint32_t)x,(uint32_t)(x>>32))))
#define Sigma1(x) (((uint64_t)sha512sum1r((uint32_t)(x>>32),(uint32_t)x))<<32 | ((uint64_t)sha512sum1r((uint32_t)x,(uint32_t)(x>>32))))
#define sigma0(x) (((uint64_t)sha512sig0h((uint32_t)(x>>32),(uint32_t)x))<<32 | ((uint64_t)sha512sig0l((uint32_t)x,(uint32_t)(x>>32))))
#define sigma1(x) (((uint64_t)sha512sig1h((uint32_t)(x>>32),(uint32_t)x))<<32 | ((uint64_t)sha512sig1l((uint32_t)x,(uint32_t)(x>>32))))
#endif
#define M(w0,w14,w9,w1) w0 = sigma1(w14) + w9 + sigma0(w1) + w0;
#define EXPAND \
M(w0 ,w14,w9 ,w1 ) \
M(w1 ,w15,w10,w2 ) \
M(w2 ,w0 ,w11,w3 ) \
M(w3 ,w1 ,w12,w4 ) \
M(w4 ,w2 ,w13,w5 ) \
M(w5 ,w3 ,w14,w6 ) \
M(w6 ,w4 ,w15,w7 ) \
M(w7 ,w5 ,w0 ,w8 ) \
M(w8 ,w6 ,w1 ,w9 ) \
M(w9 ,w7 ,w2 ,w10) \
M(w10,w8 ,w3 ,w11) \
M(w11,w9 ,w4 ,w12) \
M(w12,w10,w5 ,w13) \
M(w13,w11,w6 ,w14) \
M(w14,w12,w7 ,w15) \
M(w15,w13,w8 ,w0 )
#define F(w,k) \
T1 = h + Sigma1(e) + Ch(e,f,g) + k + w; \
T2 = Sigma0(a) + Maj(a,b,c); \
h = g; \
g = f; \
f = e; \
e = d + T1; \
d = c; \
c = b; \
b = a; \
a = T1 + T2;
int crypto_hashblocks(unsigned char *statebytes,const unsigned char *in,unsigned long long inlen)
{
uint64 state[8];
uint64 a;
uint64 b;
uint64 c;
uint64 d;
uint64 e;
uint64 f;
uint64 g;
uint64 h;
uint64 T1;
uint64 T2;
a = load_bigendian(statebytes + 0); state[0] = a;
b = load_bigendian(statebytes + 8); state[1] = b;
c = load_bigendian(statebytes + 16); state[2] = c;
d = load_bigendian(statebytes + 24); state[3] = d;
e = load_bigendian(statebytes + 32); state[4] = e;
f = load_bigendian(statebytes + 40); state[5] = f;
g = load_bigendian(statebytes + 48); state[6] = g;
h = load_bigendian(statebytes + 56); state[7] = h;
while (inlen >= 128) {
uint64 w0 = load_bigendian(in + 0);
uint64 w1 = load_bigendian(in + 8);
uint64 w2 = load_bigendian(in + 16);
uint64 w3 = load_bigendian(in + 24);
uint64 w4 = load_bigendian(in + 32);
uint64 w5 = load_bigendian(in + 40);
uint64 w6 = load_bigendian(in + 48);
uint64 w7 = load_bigendian(in + 56);
uint64 w8 = load_bigendian(in + 64);
uint64 w9 = load_bigendian(in + 72);
uint64 w10 = load_bigendian(in + 80);
uint64 w11 = load_bigendian(in + 88);
uint64 w12 = load_bigendian(in + 96);
uint64 w13 = load_bigendian(in + 104);
uint64 w14 = load_bigendian(in + 112);
uint64 w15 = load_bigendian(in + 120);
F(w0 ,0x428a2f98d728ae22ULL)
F(w1 ,0x7137449123ef65cdULL)
F(w2 ,0xb5c0fbcfec4d3b2fULL)
F(w3 ,0xe9b5dba58189dbbcULL)
F(w4 ,0x3956c25bf348b538ULL)
F(w5 ,0x59f111f1b605d019ULL)
F(w6 ,0x923f82a4af194f9bULL)
F(w7 ,0xab1c5ed5da6d8118ULL)
F(w8 ,0xd807aa98a3030242ULL)
F(w9 ,0x12835b0145706fbeULL)
F(w10,0x243185be4ee4b28cULL)
F(w11,0x550c7dc3d5ffb4e2ULL)
F(w12,0x72be5d74f27b896fULL)
F(w13,0x80deb1fe3b1696b1ULL)
F(w14,0x9bdc06a725c71235ULL)
F(w15,0xc19bf174cf692694ULL)
EXPAND
F(w0 ,0xe49b69c19ef14ad2ULL)
F(w1 ,0xefbe4786384f25e3ULL)
F(w2 ,0x0fc19dc68b8cd5b5ULL)
F(w3 ,0x240ca1cc77ac9c65ULL)
F(w4 ,0x2de92c6f592b0275ULL)
F(w5 ,0x4a7484aa6ea6e483ULL)
F(w6 ,0x5cb0a9dcbd41fbd4ULL)
F(w7 ,0x76f988da831153b5ULL)
F(w8 ,0x983e5152ee66dfabULL)
F(w9 ,0xa831c66d2db43210ULL)
F(w10,0xb00327c898fb213fULL)
F(w11,0xbf597fc7beef0ee4ULL)
F(w12,0xc6e00bf33da88fc2ULL)
F(w13,0xd5a79147930aa725ULL)
F(w14,0x06ca6351e003826fULL)
F(w15,0x142929670a0e6e70ULL)
EXPAND
F(w0 ,0x27b70a8546d22ffcULL)
F(w1 ,0x2e1b21385c26c926ULL)
F(w2 ,0x4d2c6dfc5ac42aedULL)
F(w3 ,0x53380d139d95b3dfULL)
F(w4 ,0x650a73548baf63deULL)
F(w5 ,0x766a0abb3c77b2a8ULL)
F(w6 ,0x81c2c92e47edaee6ULL)
F(w7 ,0x92722c851482353bULL)
F(w8 ,0xa2bfe8a14cf10364ULL)
F(w9 ,0xa81a664bbc423001ULL)
F(w10,0xc24b8b70d0f89791ULL)
F(w11,0xc76c51a30654be30ULL)
F(w12,0xd192e819d6ef5218ULL)
F(w13,0xd69906245565a910ULL)
F(w14,0xf40e35855771202aULL)
F(w15,0x106aa07032bbd1b8ULL)
EXPAND
F(w0 ,0x19a4c116b8d2d0c8ULL)
F(w1 ,0x1e376c085141ab53ULL)
F(w2 ,0x2748774cdf8eeb99ULL)
F(w3 ,0x34b0bcb5e19b48a8ULL)
F(w4 ,0x391c0cb3c5c95a63ULL)
F(w5 ,0x4ed8aa4ae3418acbULL)
F(w6 ,0x5b9cca4f7763e373ULL)
F(w7 ,0x682e6ff3d6b2b8a3ULL)
F(w8 ,0x748f82ee5defb2fcULL)
F(w9 ,0x78a5636f43172f60ULL)
F(w10,0x84c87814a1f0ab72ULL)
F(w11,0x8cc702081a6439ecULL)
F(w12,0x90befffa23631e28ULL)
F(w13,0xa4506cebde82bde9ULL)
F(w14,0xbef9a3f7b2c67915ULL)
F(w15,0xc67178f2e372532bULL)
EXPAND
F(w0 ,0xca273eceea26619cULL)
F(w1 ,0xd186b8c721c0c207ULL)
F(w2 ,0xeada7dd6cde0eb1eULL)
F(w3 ,0xf57d4f7fee6ed178ULL)
F(w4 ,0x06f067aa72176fbaULL)
F(w5 ,0x0a637dc5a2c898a6ULL)
F(w6 ,0x113f9804bef90daeULL)
F(w7 ,0x1b710b35131c471bULL)
F(w8 ,0x28db77f523047d84ULL)
F(w9 ,0x32caab7b40c72493ULL)
F(w10,0x3c9ebe0a15c9bebcULL)
F(w11,0x431d67c49c100d4cULL)
F(w12,0x4cc5d4becb3e42b6ULL)
F(w13,0x597f299cfc657e2aULL)
F(w14,0x5fcb6fab3ad6faecULL)
F(w15,0x6c44198c4a475817ULL)
a += state[0];
b += state[1];
c += state[2];
d += state[3];
e += state[4];
f += state[5];
g += state[6];
h += state[7];
state[0] = a;
state[1] = b;
state[2] = c;
state[3] = d;
state[4] = e;
state[5] = f;
state[6] = g;
state[7] = h;
in += 128;
inlen -= 128;
}
store_bigendian(statebytes + 0,state[0]);
store_bigendian(statebytes + 8,state[1]);
store_bigendian(statebytes + 16,state[2]);
store_bigendian(statebytes + 24,state[3]);
store_bigendian(statebytes + 32,state[4]);
store_bigendian(statebytes + 40,state[5]);
store_bigendian(statebytes + 48,state[6]);
store_bigendian(statebytes + 56,state[7]);
return inlen;
}

View file

@ -0,0 +1,28 @@
/*
cpucycles riscv.h version 20190803
D. J. Bernstein
Romain Dolbeau
Public domain.
*/
#ifndef CPUCYCLES_riscv_h
#define CPUCYCLES_riscv_h
#ifdef __cplusplus
extern "C" {
#endif
extern long long cpucycles_riscv(void);
extern long long cpucycles_riscv_persecond(void);
#ifdef __cplusplus
}
#endif
#ifndef cpucycles_implementation
#define cpucycles_implementation "riscv"
#define cpucycles cpucycles_riscv
#define cpucycles_persecond cpucycles_riscv_persecond
#endif
#endif

View file

@ -0,0 +1,13 @@
#ifndef crypto_hashblocks_H
#define crypto_hashblocks_H
#include "crypto_hashblocks_sha512.h"
#define crypto_hashblocks crypto_hashblocks_sha512
#define crypto_hashblocks_STATEBYTES crypto_hashblocks_sha512_STATEBYTES
#define crypto_hashblocks_BLOCKBYTES crypto_hashblocks_sha512_BLOCKBYTES
#define crypto_hashblocks_PRIMITIVE "sha512"
#define crypto_hashblocks_IMPLEMENTATION crypto_hashblocks_sha512_IMPLEMENTATION
#define crypto_hashblocks_VERSION crypto_hashblocks_sha512_VERSION
#endif

View file

@ -0,0 +1,24 @@
#ifndef crypto_hashblocks_sha256_H
#define crypto_hashblocks_sha256_H
#define crypto_hashblocks_sha256_inplace_STATEBYTES 32
#define crypto_hashblocks_sha256_inplace_BLOCKBYTES 64
#ifdef __cplusplus
extern "C" {
#endif
extern int crypto_hashblocks_sha256_inplace(unsigned char *,const unsigned char *,unsigned long long);
#ifdef __cplusplus
}
#endif
#define crypto_hashblocks_sha256 crypto_hashblocks_sha256_inplace
#define crypto_hashblocks_sha256_STATEBYTES crypto_hashblocks_sha256_inplace_STATEBYTES
#define crypto_hashblocks_sha256_BLOCKBYTES crypto_hashblocks_sha256_inplace_BLOCKBYTES
#define crypto_hashblocks_sha256_IMPLEMENTATION "crypto_hashblocks/sha256/inplace"
#ifndef crypto_hashblocks_sha256_inplace_VERSION
#define crypto_hashblocks_sha256_inplace_VERSION "-"
#endif
#define crypto_hashblocks_sha256_VERSION crypto_hashblocks_sha256_inplace_VERSION
#endif

View file

@ -0,0 +1,24 @@
#ifndef crypto_hashblocks_sha512_H
#define crypto_hashblocks_sha512_H
#define crypto_hashblocks_sha512_inplace_STATEBYTES 64
#define crypto_hashblocks_sha512_inplace_BLOCKBYTES 128
#ifdef __cplusplus
extern "C" {
#endif
extern int crypto_hashblocks_sha512_inplace(unsigned char *,const unsigned char *,unsigned long long);
#ifdef __cplusplus
}
#endif
#define crypto_hashblocks_sha512 crypto_hashblocks_sha512_inplace
#define crypto_hashblocks_sha512_STATEBYTES crypto_hashblocks_sha512_inplace_STATEBYTES
#define crypto_hashblocks_sha512_BLOCKBYTES crypto_hashblocks_sha512_inplace_BLOCKBYTES
#define crypto_hashblocks_sha512_IMPLEMENTATION "crypto_hashblocks/sha512/inplace"
#ifndef crypto_hashblocks_sha512_inplace_VERSION
#define crypto_hashblocks_sha512_inplace_VERSION "-"
#endif
#define crypto_hashblocks_sha512_VERSION crypto_hashblocks_sha512_inplace_VERSION
#endif

View file

@ -0,0 +1,6 @@
#ifndef crypto_uint32_h
#define crypto_uint32_h
typedef unsigned int crypto_uint32;
#endif

View file

@ -0,0 +1,6 @@
#ifndef crypto_uint64_h
#define crypto_uint64_h
typedef unsigned long long crypto_uint64;
#endif

View file

@ -0,0 +1,6 @@
#ifndef crypto_uint8_h
#define crypto_uint8_h
typedef unsigned char crypto_uint8;
#endif

View file

@ -0,0 +1 @@
Daniel J. Bernstein

View file

@ -0,0 +1,14 @@
#ifndef kernelrandombytes_h
#define kernelrandombytes_h
#ifdef __cplusplus
extern "C" {
#endif
extern void kernelrandombytes(unsigned char *,unsigned long long);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,19 @@
#include <random>
#include <functional>
std::default_random_engine generator;
std::uniform_int_distribution<unsigned char> distribution(0,255);
auto rbyte = std::bind ( distribution, generator );
extern "C" {
void kernelrandombytes(unsigned char *x,unsigned long long xlen)
{
int i;
while (xlen > 0) {
*x = rbyte();
x++;
xlen--;
}
}
}

View file

@ -0,0 +1,83 @@
/*
cpucycles/riscv.c version 20190803
D. J. Bernstein
Romain Dolbeau
Public domain.
*/
#include <time.h>
#include <sys/time.h>
#include <sys/types.h>
long long cpucycles_riscv(void)
{
long long result;
#if defined(__riscv_xlen)
#if __riscv_xlen == 64
asm volatile("rdcycle %0" : "=r" (result));
#elif __riscv_xlen == 32
unsigned int l, h, h2;
asm volatile( "start:\n"
"rdcycleh %0\n"
"rdcycle %1\n"
"rdcycleh %2\n"
"bne %0, %2, start\n"
: "=r" (h), "=r" (l), "=r" (h2));
result = (((unsigned long long)h)<<32) | ((unsigned long long)l);
#else
#error "unknown __riscv_xlen"
#endif
#else // __riscv_xlen
#error "__riscv_xlen required for RISC-V support"
#endif // __riscv_xlen
return result;
}
static long long microseconds(void)
{
struct timeval t;
gettimeofday(&t,(struct timezone *) 0);
return t.tv_sec * (long long) 1000000 + t.tv_usec;
}
static double guessfreq(void)
{
long long tb0; long long us0;
long long tb1; long long us1;
tb0 = cpucycles_riscv();
us0 = microseconds();
do {
tb1 = cpucycles_riscv();
us1 = microseconds();
} while (us1 - us0 < 10000 || tb1 - tb0 < 1000);
if (tb1 <= tb0) return 0;
tb1 -= tb0;
us1 -= us0;
return ((double) tb1) / (0.000001 * (double) us1);
}
static long long cpufrequency = 0;
static void init(void)
{
double guess1;
double guess2;
int loop;
for (loop = 0;loop < 100;++loop) {
guess1 = guessfreq();
guess2 = guessfreq();
if (guess1 > 1.01 * guess2) continue;
if (guess2 > 1.01 * guess1) continue;
cpufrequency = 0.5 * (guess1 + guess2);
break;
}
}
long long cpucycles_riscv_persecond(void)
{
if (!cpufrequency) init();
return cpufrequency;
}

View file

@ -0,0 +1,323 @@
/*
* try-anything.c version 20190729
* D. J. Bernstein
* Some portions adapted from TweetNaCl by Bernstein, Janssen, Lange, Schwabe.
* Public domain.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/resource.h>
#include "kernelrandombytes.h"
#include "cpucycles.h"
#include "crypto_uint8.h"
#include "crypto_uint32.h"
#include "crypto_uint64.h"
#include "try.h"
typedef crypto_uint8 u8;
typedef crypto_uint32 u32;
typedef crypto_uint64 u64;
#define FOR(i,n) for (i = 0;i < n;++i)
static u32 L32(u32 x,int c) { return (x << c) | ((x&0xffffffff) >> (32 - c)); }
static u32 ld32(const u8 *x)
{
u32 u = x[3];
u = (u<<8)|x[2];
u = (u<<8)|x[1];
return (u<<8)|x[0];
}
static void st32(u8 *x,u32 u)
{
int i;
FOR(i,4) { x[i] = u; u >>= 8; }
}
static const u8 sigma[17] = "expand 32-byte k";
static void core(u8 *out,const u8 *in,const u8 *k)
{
u32 w[16],x[16],y[16],t[4];
int i,j,m;
FOR(i,4) {
x[5*i] = ld32(sigma+4*i);
x[1+i] = ld32(k+4*i);
x[6+i] = ld32(in+4*i);
x[11+i] = ld32(k+16+4*i);
}
FOR(i,16) y[i] = x[i];
FOR(i,20) {
FOR(j,4) {
FOR(m,4) t[m] = x[(5*j+4*m)%16];
t[1] ^= L32(t[0]+t[3], 7);
t[2] ^= L32(t[1]+t[0], 9);
t[3] ^= L32(t[2]+t[1],13);
t[0] ^= L32(t[3]+t[2],18);
FOR(m,4) w[4*j+(j+m)%4] = t[m];
}
FOR(m,16) x[m] = w[m];
}
FOR(i,16) st32(out + 4 * i,x[i] + y[i]);
}
static void salsa20(u8 *c,u64 b,const u8 *n,const u8 *k)
{
u8 z[16],x[64];
u32 u,i;
if (!b) return;
FOR(i,16) z[i] = 0;
FOR(i,8) z[i] = n[i];
while (b >= 64) {
core(x,z,k);
FOR(i,64) c[i] = x[i];
u = 1;
for (i = 8;i < 16;++i) {
u += (u32) z[i];
z[i] = u;
u >>= 8;
}
b -= 64;
c += 64;
}
if (b) {
core(x,z,k);
FOR(i,b) c[i] = x[i];
}
}
static void increment(u8 *n)
{
if (!++n[0])
if (!++n[1])
if (!++n[2])
if (!++n[3])
if (!++n[4])
if (!++n[5])
if (!++n[6])
if (!++n[7])
;
}
static void testvector(unsigned char *x,unsigned long long xlen)
{
const static unsigned char testvector_k[33] = "generate inputs for test vectors";
static unsigned char testvector_n[8];
salsa20(x,xlen,testvector_n,testvector_k);
increment(testvector_n);
}
unsigned long long myrandom(void)
{
unsigned char x[8];
unsigned long long result;
testvector(x,8);
result = x[7];
result = (result<<8)|x[6];
result = (result<<8)|x[5];
result = (result<<8)|x[4];
result = (result<<8)|x[3];
result = (result<<8)|x[2];
result = (result<<8)|x[1];
result = (result<<8)|x[0];
return result;
}
static void canary(unsigned char *x,unsigned long long xlen)
{
const static unsigned char canary_k[33] = "generate pad to catch overwrites";
static unsigned char canary_n[8];
salsa20(x,xlen,canary_n,canary_k);
increment(canary_n);
}
void double_canary(unsigned char *x2,unsigned char *x,unsigned long long xlen)
{
canary(x - 16,16);
canary(x + xlen,16);
memcpy(x2 - 16,x - 16,16);
memcpy(x2 + xlen,x + xlen,16);
}
void input_prepare(unsigned char *x2,unsigned char *x,unsigned long long xlen)
{
testvector(x,xlen);
canary(x - 16,16);
canary(x + xlen,16);
memcpy(x2 - 16,x - 16,xlen + 32);
}
void input_compare(const unsigned char *x2,const unsigned char *x,unsigned long long xlen,const char *fun)
{
if (memcmp(x2 - 16,x - 16,xlen + 32)) {
fprintf(stderr,"%s overwrites input\n",fun);
exit(111);
}
}
void output_prepare(unsigned char *x2,unsigned char *x,unsigned long long xlen)
{
canary(x - 16,xlen + 32);
memcpy(x2 - 16,x - 16,xlen + 32);
}
void output_compare(const unsigned char *x2,const unsigned char *x,unsigned long long xlen,const char *fun)
{
if (memcmp(x2 - 16,x - 16,16)) {
fprintf(stderr,"%s writes before output\n",fun);
exit(111);
}
if (memcmp(x2 + xlen,x + xlen,16)) {
fprintf(stderr,"%s writes after output\n",fun);
exit(111);
}
}
static unsigned char checksum_state[64];
static char checksum_hex[65];
void checksum(const unsigned char *x,unsigned long long xlen)
{
u8 block[16];
int i;
while (xlen >= 16) {
core(checksum_state,x,checksum_state);
x += 16;
xlen -= 16;
}
FOR(i,16) block[i] = 0;
FOR(i,xlen) block[i] = x[i];
block[xlen] = 1;
checksum_state[0] ^= 1;
core(checksum_state,block,checksum_state);
}
static void printword(const char *s)
{
if (!*s) putchar('-');
while (*s) {
if (*s == ' ') putchar('_');
else if (*s == '\t') putchar('_');
else if (*s == '\r') putchar('_');
else if (*s == '\n') putchar('_');
else putchar(*s);
++s;
}
putchar(' ');
}
static void printnum(long long x)
{
printf("%lld ",x);
}
void fail(const char *why)
{
fprintf(stderr,"%s\n",why);
exit(111);
}
unsigned char *alignedcalloc(unsigned long long len)
{
unsigned char *x = (unsigned char *) calloc(1,len + 256);
long long i;
if (!x) fail("out of memory");
/* will never deallocate so shifting is ok */
for (i = 0;i < len + 256;++i) x[i] = random();
x += 64;
x += 63 & (-(unsigned long) x);
for (i = 0;i < len;++i) x[i] = 0;
return x;
}
#define TIMINGS 63
static long long cycles[TIMINGS + 1];
void limits()
{
#ifdef RLIM_INFINITY
struct rlimit r;
r.rlim_cur = 0;
r.rlim_max = 0;
#ifdef RLIMIT_NOFILE
setrlimit(RLIMIT_NOFILE,&r);
#endif
#ifdef RLIMIT_NPROC
setrlimit(RLIMIT_NPROC,&r);
#endif
#ifdef RLIMIT_CORE
setrlimit(RLIMIT_CORE,&r);
#endif
#endif
}
static unsigned char randombyte[1];
int main()
{
long long i;
long long j;
long long abovej;
long long belowj;
long long checksumcycles;
long long cyclespersecond;
cycles[0] = cpucycles();
cycles[1] = cpucycles();
cyclespersecond = cpucycles_persecond();
kernelrandombytes(randombyte,1);
preallocate();
limits();
allocate();
srandom(getpid());
cycles[0] = cpucycles();
test();
cycles[1] = cpucycles();
checksumcycles = cycles[1] - cycles[0];
predoit();
for (i = 0;i <= TIMINGS;++i) {
cycles[i] = cpucycles();
}
for (i = 0;i <= TIMINGS;++i) {
cycles[i] = cpucycles();
doit();
}
for (i = 0;i < TIMINGS;++i) cycles[i] = cycles[i + 1] - cycles[i];
for (j = 0;j < TIMINGS;++j) {
belowj = 0;
for (i = 0;i < TIMINGS;++i) if (cycles[i] < cycles[j]) ++belowj;
abovej = 0;
for (i = 0;i < TIMINGS;++i) if (cycles[i] > cycles[j]) ++abovej;
if (belowj * 2 < TIMINGS && abovej * 2 < TIMINGS) break;
}
for (i = 0;i < 32;++i) {
checksum_hex[2 * i] = "0123456789abcdef"[15 & (checksum_state[i] >> 4)];
checksum_hex[2 * i + 1] = "0123456789abcdef"[15 & checksum_state[i]];
}
checksum_hex[2 * i] = 0;
printword(checksum_hex);
printnum(cycles[j]);
printnum(checksumcycles);
printnum(cyclespersecond);
printword(primitiveimplementation);
printf("\n");
return 0;
}

View file

@ -0,0 +1,76 @@
/*
* crypto_hashblocks/try.c version 20200406
* D. J. Bernstein
* Public domain.
* Auto-generated by trygen.py; do not edit.
*/
#include "crypto_hashblocks.h"
#include "try.h"
const char *primitiveimplementation = crypto_hashblocks_IMPLEMENTATION;
#define TUNE_BYTES 1536
#ifdef SMALL
#define MAXTEST_BYTES 128
#else
#define MAXTEST_BYTES 4096
#endif
#ifdef SMALL
#define LOOPS 4096
#else
#define LOOPS 32768
#endif
static unsigned char *h;
static unsigned char *m;
static unsigned char *h2;
static unsigned char *m2;
#define hlen crypto_hashblocks_STATEBYTES
unsigned long long mlen;
void preallocate(void)
{
}
void allocate(void)
{
unsigned long long alloclen = 0;
if (alloclen < TUNE_BYTES) alloclen = TUNE_BYTES;
if (alloclen < MAXTEST_BYTES) alloclen = MAXTEST_BYTES;
if (alloclen < crypto_hashblocks_STATEBYTES) alloclen = crypto_hashblocks_STATEBYTES;
h = alignedcalloc(alloclen);
m = alignedcalloc(alloclen);
h2 = alignedcalloc(alloclen);
m2 = alignedcalloc(alloclen);
}
void predoit(void)
{
}
void doit(void)
{
crypto_hashblocks(h,m,TUNE_BYTES);
}
void test(void)
{
unsigned long long loop;
for (loop = 0;loop < LOOPS;++loop) {
mlen = myrandom() % (MAXTEST_BYTES + 1);
input_prepare(m2,m,mlen);
input_prepare(h2,h,hlen);
if (crypto_hashblocks(h,m,mlen) != mlen % crypto_hashblocks_BLOCKBYTES) fail("crypto_hashblocks returns unexpected value");
checksum(h,hlen);
output_compare(h2,h,hlen,"crypto_hashblocks");
input_compare(m2,m,mlen,"crypto_hashblocks");
double_canary(h2,h,hlen);
double_canary(m2,m,mlen);
if (crypto_hashblocks(h2,m2,mlen) != mlen % crypto_hashblocks_BLOCKBYTES) fail("crypto_hashblocks returns unexpected value");
if (memcmp(h2,h,hlen) != 0) fail("crypto_hashblocks is nondeterministic");
}
}

View file

@ -0,0 +1,21 @@
#include <stdlib.h>
#include <string.h>
/* provided by try.c: */
extern const char *primitiveimplementation;
extern void preallocate(void);
extern void allocate(void);;
extern void test(void);
extern void predoit(void);
extern void doit(void);
/* provided by try-anything.c: */
extern void fail(const char *);
extern unsigned char *alignedcalloc(unsigned long long);
extern void checksum(const unsigned char *,unsigned long long);
extern void double_canary(unsigned char *,unsigned char *,unsigned long long);
extern void input_prepare(unsigned char *,unsigned char *,unsigned long long);
extern void output_prepare(unsigned char *,unsigned char *,unsigned long long);
extern void input_compare(const unsigned char *,const unsigned char *,unsigned long long,const char *);
extern void output_compare(const unsigned char *,const unsigned char *,unsigned long long,const char *);
extern unsigned long long myrandom(void);