Add sha256* from Zknh, and associated Supercop test

This commit is contained in:
Romain Dolbeau 2020-11-11 09:43:15 -05:00
parent 7200b48ecb
commit 3190619c2b
19 changed files with 1113 additions and 2 deletions

106
CryptoZknh.scala Normal file
View file

@ -0,0 +1,106 @@
// WARNING: this is auto-generated code!
// See https://github.com/rdolbeau/VexRiscvBPluginGenerator/
package vexriscv.plugin
import spinal.core._
import vexriscv.{Stageable, DecoderService, VexRiscv}
object CryptoZknhPlugin {
object CryptoZknhCtrlsha256sigEnum extends SpinalEnum(binarySequential) {
val CTRL_sha256sig0, CTRL_sha256sig1 = newElement()
}
object CryptoZknhCtrlsha256sumEnum extends SpinalEnum(binarySequential) {
val CTRL_sha256sum0, CTRL_sha256sum1 = newElement()
}
object CryptoZknhCtrlEnum extends SpinalEnum(binarySequential) {
val CTRL_sha256sig, CTRL_sha256sum = newElement()
}
object CryptoZknhCtrlsha256sig extends Stageable(CryptoZknhCtrlsha256sigEnum())
object CryptoZknhCtrlsha256sum extends Stageable(CryptoZknhCtrlsha256sumEnum())
object CryptoZknhCtrl extends Stageable(CryptoZknhCtrlEnum())
// Prologue
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 = {
val r = rs1.rotateRight(17) ^ rs1.rotateRight(19) ^ (rs1 |>> 10)
r // return value
}
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 = {
val r = rs1.rotateRight(6) ^ rs1.rotateRight(11) ^ rs1.rotateRight(25)
r // return value
}
// End prologue
} // object Plugin
class CryptoZknhPlugin extends Plugin[VexRiscv] {
import CryptoZknhPlugin._
object IS_CryptoZknh extends Stageable(Bool)
override def setup(pipeline: VexRiscv): Unit = {
import pipeline.config._
val immediateActions = List[(Stageable[_ <: BaseType],Any)](
SRC1_CTRL -> Src1CtrlEnum.RS,
SRC2_CTRL -> Src2CtrlEnum.IMI,
REGFILE_WRITE_VALID -> True,
BYPASSABLE_EXECUTE_STAGE -> True,
BYPASSABLE_MEMORY_STAGE -> True,
RS1_USE -> True,
IS_CryptoZknh -> True
)
val binaryActions = List[(Stageable[_ <: BaseType],Any)](
SRC1_CTRL -> Src1CtrlEnum.RS,
SRC2_CTRL -> Src2CtrlEnum.RS,
REGFILE_WRITE_VALID -> True,
BYPASSABLE_EXECUTE_STAGE -> True,
BYPASSABLE_MEMORY_STAGE -> True,
RS1_USE -> True,
RS2_USE -> True,
IS_CryptoZknh -> True
)
val unaryActions = List[(Stageable[_ <: BaseType],Any)](
SRC1_CTRL -> Src1CtrlEnum.RS,
REGFILE_WRITE_VALID -> True,
BYPASSABLE_EXECUTE_STAGE -> True,
BYPASSABLE_MEMORY_STAGE -> True,
RS1_USE -> True,
IS_CryptoZknh -> True
)
def sha256sig0_KEY = M"000011100000-----111-----0101011"
def sha256sig1_KEY = M"000011100001-----111-----0101011"
def sha256sum0_KEY = M"000011100010-----111-----0101011"
def sha256sum1_KEY = M"000011100011-----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))
))
} // override def setup
override def build(pipeline: VexRiscv): Unit = {
import pipeline._
import pipeline.config._
execute plug new Area{
import execute._
val val_sha256sig = input(CryptoZknhCtrlsha256sig).mux(
CryptoZknhCtrlsha256sigEnum.CTRL_sha256sig0 -> fun_sha256sig0(input(SRC1)),
CryptoZknhCtrlsha256sigEnum.CTRL_sha256sig1 -> fun_sha256sig1(input(SRC1))
) // mux sha256sig
val val_sha256sum = input(CryptoZknhCtrlsha256sum).mux(
CryptoZknhCtrlsha256sumEnum.CTRL_sha256sum0 -> fun_sha256sum0(input(SRC1)),
CryptoZknhCtrlsha256sumEnum.CTRL_sha256sum1 -> fun_sha256sum1(input(SRC1))
) // mux sha256sum
when (input(IS_CryptoZknh)) {
execute.output(REGFILE_WRITE_DATA) := input(CryptoZknhCtrl).mux(
CryptoZknhCtrlEnum.CTRL_sha256sig -> val_sha256sig.asBits,
CryptoZknhCtrlEnum.CTRL_sha256sum -> val_sha256sum.asBits
) // primary mux
} // when input is
} // execute plug newArea
} // override def build
} // class Plugin

View file

@ -53,6 +53,9 @@ CryptoZknePlugin.scala: gen_plugin data_aes.txt
BitManipZclmul.scala: gen_plugin data_clmul.txt
./gen_plugin BitManipZclmul data_clmul.txt '*' >| $@
scala: BitManipZbpPlugin.scala BitManipAllPlugin.scala CryptoZknePlugin.scala BitManipZclmul.scala
CryptoZknh.scala: gen_plugin data_sha256.txt
./gen_plugin CryptoZknh data_sha256.txt '*' >| $@
include $(DEPXX)
scala: BitManipZbpPlugin.scala BitManipAllPlugin.scala CryptoZknePlugin.scala BitManipZclmul.scala CryptoZknh.scala
include $(DEPXX)

45
data_sha256.txt Normal file
View file

@ -0,0 +1,45 @@
//#define MATCH_SHA256SIG0 0xe00702b
//#define MASK_SHA256SIG0 0xfff0707f
//#define MATCH_SHA256SIG1 0xe10702b
//#define MASK_SHA256SIG1 0xfff0707f
//#define MATCH_SHA256SUM0 0xe20702b
//#define MASK_SHA256SUM0 0xfff0707f
//#define MATCH_SHA256SUM1 0xe30702b
//#define MASK_SHA256SUM1 0xfff0707f
//{"sha256sig0" , 0, INSN_CLASS_I, "d,s", MATCH_SHA256SIG0, MASK_SHA256SIG0, match_opcode, 0},
//{"sha256sig1" , 0, INSN_CLASS_I, "d,s", MATCH_SHA256SIG1, MASK_SHA256SIG1, match_opcode, 0},
//{"sha256sum0" , 0, INSN_CLASS_I, "d,s", MATCH_SHA256SUM0, MASK_SHA256SUM0, match_opcode, 0},
//{"sha256sum1" , 0, INSN_CLASS_I, "d,s", MATCH_SHA256SUM1, MASK_SHA256SUM1, match_opcode, 0},
//0000111 00000 rs1 111 rd 0101011 sha256sig0
//0000111 00001 rs1 111 rd 0101011 sha256sig1
//0000111 00010 rs1 111 rd 0101011 sha256sum0
//0000111 00011 rs1 111 rd 0101011 sha256sum1
I sha256sig0 sha256sig0 000011100000-----111-----0101011 sha256sig Zknh
I sha256sig1 sha256sig1 000011100001-----111-----0101011 sha256sig Zknh
I sha256sum0 sha256sum0 000011100010-----111-----0101011 sha256sum Zknh
I sha256sum1 sha256sum1 000011100011-----111-----0101011 sha256sum Zknh
S sha256sig0 "fun_sha256sig0(input(SRC1))"
S sha256sig1 "fun_sha256sig1(input(SRC1))"
S sha256sum0 "fun_sha256sum0(input(SRC1))"
S sha256sum1 "fun_sha256sum1(input(SRC1))"
P """
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 = {
val r = rs1.rotateRight(17) ^ rs1.rotateRight(19) ^ (rs1 |>> 10)
r // return value
}
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 = {
val r = rs1.rotateRight(6) ^ rs1.rotateRight(11) ^ rs1.rotateRight(25)
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: sha256 sha256_small
clean:
rm -f $(OBJs) try.o try_small.o blocks.o sha256 sha256_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 $@
sha256: $(OBJs) blocks.o try.o $(SCLIBS)
$(CXX) $(OPT) $^ -o $@
sha256_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 32
#define CRYPTO_BLOCKBYTES 64

View file

@ -0,0 +1,288 @@
#include "crypto_hashblocks.h"
typedef unsigned int uint32;
#ifdef RV32ZKNH
typedef unsigned int uint32_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; \
}
ASM1MACRO(SHA256SIG0,0x0e00702b)
ASM1MACRO(SHA256SIG1,0x0e10702b)
ASM1MACRO(SHA256SUM0,0x0e20702b)
ASM1MACRO(SHA256SUM1,0x0e30702b)
FUN1(sha256sig0,SHA256SIG0)
FUN1(sha256sig1,SHA256SIG1)
FUN1(sha256sum0,SHA256SUM0)
FUN1(sha256sum1,SHA256SUM1)
#endif
static uint32 load_bigendian(const unsigned char *x)
{
return
(uint32) (x[3]) \
| (((uint32) (x[2])) << 8) \
| (((uint32) (x[1])) << 16) \
| (((uint32) (x[0])) << 24)
;
}
static void store_bigendian(unsigned char *x,uint32 u)
{
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) << (32 - (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, 2) ^ ROTR(x,13) ^ ROTR(x,22))
#define Sigma1(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
#define sigma0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
#define sigma1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
#else
#define Sigma0(x) sha256sum0(x)
#define Sigma1(x) sha256sum1(x)
#define sigma0(x) sha256sig0(x)
#define sigma1(x) sha256sig1(x)
#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)
{
uint32 state[8];
uint32 a;
uint32 b;
uint32 c;
uint32 d;
uint32 e;
uint32 f;
uint32 g;
uint32 h;
uint32 T1;
uint32 T2;
a = load_bigendian(statebytes + 0); state[0] = a;
b = load_bigendian(statebytes + 4); state[1] = b;
c = load_bigendian(statebytes + 8); state[2] = c;
d = load_bigendian(statebytes + 12); state[3] = d;
e = load_bigendian(statebytes + 16); state[4] = e;
f = load_bigendian(statebytes + 20); state[5] = f;
g = load_bigendian(statebytes + 24); state[6] = g;
h = load_bigendian(statebytes + 28); state[7] = h;
while (inlen >= 64) {
uint32 w0 = load_bigendian(in + 0);
uint32 w1 = load_bigendian(in + 4);
uint32 w2 = load_bigendian(in + 8);
uint32 w3 = load_bigendian(in + 12);
uint32 w4 = load_bigendian(in + 16);
uint32 w5 = load_bigendian(in + 20);
uint32 w6 = load_bigendian(in + 24);
uint32 w7 = load_bigendian(in + 28);
uint32 w8 = load_bigendian(in + 32);
uint32 w9 = load_bigendian(in + 36);
uint32 w10 = load_bigendian(in + 40);
uint32 w11 = load_bigendian(in + 44);
uint32 w12 = load_bigendian(in + 48);
uint32 w13 = load_bigendian(in + 52);
uint32 w14 = load_bigendian(in + 56);
uint32 w15 = load_bigendian(in + 60);
F(w0 ,0x428a2f98)
F(w1 ,0x71374491)
F(w2 ,0xb5c0fbcf)
F(w3 ,0xe9b5dba5)
F(w4 ,0x3956c25b)
F(w5 ,0x59f111f1)
F(w6 ,0x923f82a4)
F(w7 ,0xab1c5ed5)
F(w8 ,0xd807aa98)
F(w9 ,0x12835b01)
F(w10,0x243185be)
F(w11,0x550c7dc3)
F(w12,0x72be5d74)
F(w13,0x80deb1fe)
F(w14,0x9bdc06a7)
F(w15,0xc19bf174)
EXPAND
F(w0 ,0xe49b69c1)
F(w1 ,0xefbe4786)
F(w2 ,0x0fc19dc6)
F(w3 ,0x240ca1cc)
F(w4 ,0x2de92c6f)
F(w5 ,0x4a7484aa)
F(w6 ,0x5cb0a9dc)
F(w7 ,0x76f988da)
F(w8 ,0x983e5152)
F(w9 ,0xa831c66d)
F(w10,0xb00327c8)
F(w11,0xbf597fc7)
F(w12,0xc6e00bf3)
F(w13,0xd5a79147)
F(w14,0x06ca6351)
F(w15,0x14292967)
EXPAND
F(w0 ,0x27b70a85)
F(w1 ,0x2e1b2138)
F(w2 ,0x4d2c6dfc)
F(w3 ,0x53380d13)
F(w4 ,0x650a7354)
F(w5 ,0x766a0abb)
F(w6 ,0x81c2c92e)
F(w7 ,0x92722c85)
F(w8 ,0xa2bfe8a1)
F(w9 ,0xa81a664b)
F(w10,0xc24b8b70)
F(w11,0xc76c51a3)
F(w12,0xd192e819)
F(w13,0xd6990624)
F(w14,0xf40e3585)
F(w15,0x106aa070)
EXPAND
F(w0 ,0x19a4c116)
F(w1 ,0x1e376c08)
F(w2 ,0x2748774c)
F(w3 ,0x34b0bcb5)
F(w4 ,0x391c0cb3)
F(w5 ,0x4ed8aa4a)
F(w6 ,0x5b9cca4f)
F(w7 ,0x682e6ff3)
F(w8 ,0x748f82ee)
F(w9 ,0x78a5636f)
F(w10,0x84c87814)
F(w11,0x8cc70208)
F(w12,0x90befffa)
F(w13,0xa4506ceb)
F(w14,0xbef9a3f7)
F(w15,0xc67178f2)
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 += 64;
inlen -= 64;
}
store_bigendian(statebytes + 0,state[0]);
store_bigendian(statebytes + 4,state[1]);
store_bigendian(statebytes + 8,state[2]);
store_bigendian(statebytes + 12,state[3]);
store_bigendian(statebytes + 16,state[4]);
store_bigendian(statebytes + 20,state[5]);
store_bigendian(statebytes + 24,state[6]);
store_bigendian(statebytes + 28,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_sha256.h"
#define crypto_hashblocks crypto_hashblocks_sha256
#define crypto_hashblocks_STATEBYTES crypto_hashblocks_sha256_STATEBYTES
#define crypto_hashblocks_BLOCKBYTES crypto_hashblocks_sha256_BLOCKBYTES
#define crypto_hashblocks_PRIMITIVE "sha256"
#define crypto_hashblocks_IMPLEMENTATION crypto_hashblocks_sha256_IMPLEMENTATION
#define crypto_hashblocks_VERSION crypto_hashblocks_sha256_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,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);