adds initial version of lwc
This commit is contained in:
29
lwc/src/jambu/Makefile.in
Normal file
29
lwc/src/jambu/Makefile.in
Normal file
@@ -0,0 +1,29 @@
|
||||
# Copyright (C) 2021 SCARV project <info@scarv.org>
|
||||
#
|
||||
# Use of this source code is restricted per the MIT license, a copy of which
|
||||
# can be found at https://opensource.org/licenses/MIT (or should be included
|
||||
# as LICENSE.txt within the associated archive or repository).
|
||||
|
||||
# =============================================================================
|
||||
|
||||
ifeq "${API}" "aead"
|
||||
export NIST_HOME ?= ${REPO_HOME}/src/sw/jambu/nist/Implementations/crypto_aead/tinyjambu128v2
|
||||
export NIST_IMP ?= opt
|
||||
export NIST_KAT ?= ${NIST_HOME}/LWC_AEAD_KAT_128_96.txt
|
||||
|
||||
export NIST_INCLUDES = ${NIST_HOME}/${NIST_IMP}
|
||||
|
||||
export NIST_SOURCES = $(wildcard ${NIST_HOME}/${NIST_IMP}/*.c )
|
||||
export NIST_SOURCES += $(wildcard ${NIST_HOME}/${NIST_IMP}/*.cpp)
|
||||
export NIST_SOURCES += $(wildcard ${NIST_HOME}/${NIST_IMP}/*.s )
|
||||
export NIST_SOURCES += $(wildcard ${NIST_HOME}/${NIST_IMP}/*.S )
|
||||
export NIST_HEADERS = $(wildcard ${NIST_HOME}/${NIST_IMP}/*.h )
|
||||
endif
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
ifeq "${API}" "hash"
|
||||
$(error "${ALG} doesn't support the ${API} API")
|
||||
endif
|
||||
|
||||
# =============================================================================
|
32
lwc/src/jambu/arch/rv32/ise.h
Normal file
32
lwc/src/jambu/arch/rv32/ise.h
Normal file
@@ -0,0 +1,32 @@
|
||||
// Copyright (C) 2021 SCARV project <info@scarv.org>
|
||||
//
|
||||
// Use of this source code is restricted per the MIT license, a copy of which
|
||||
// can be found at https://opensource.org/licenses/MIT (or should be included
|
||||
// as LICENSE.txt within the associated archive or repository).
|
||||
|
||||
// ============================================================================
|
||||
|
||||
#if ( JAMBU_RV32_TYPE2 )
|
||||
.macro jambu.fsri rd, rs1, rs2, imm
|
||||
.insn r CUSTOM_1, 7, \imm+( 0*32), \rd, \rs1, \rs2
|
||||
.endm
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#if ( JAMBU_RV32_TYPE3 )
|
||||
.macro jambu.fsr.15 rd, rs1, rs2
|
||||
.insn r CUSTOM_3, 7, ( 0* 1), \rd, \rs1, \rs2
|
||||
.endm
|
||||
.macro jambu.fsr.6 rd, rs1, rs2
|
||||
.insn r CUSTOM_3, 7, ( 1* 1), \rd, \rs1, \rs2
|
||||
.endm
|
||||
.macro jambu.fsr.21 rd, rs1, rs2
|
||||
.insn r CUSTOM_3, 7, ( 2* 1), \rd, \rs1, \rs2
|
||||
.endm
|
||||
.macro jambu.fsr.27 rd, rs1, rs2
|
||||
.insn r CUSTOM_3, 7, ( 3* 1), \rd, \rs1, \rs2
|
||||
.endm
|
||||
#endif
|
||||
|
||||
// ============================================================================
|
24
lwc/src/jambu/arch/rv64/ise.h
Normal file
24
lwc/src/jambu/arch/rv64/ise.h
Normal file
@@ -0,0 +1,24 @@
|
||||
// Copyright (C) 2021 SCARV project <info@scarv.org>
|
||||
//
|
||||
// Use of this source code is restricted per the MIT license, a copy of which
|
||||
// can be found at https://opensource.org/licenses/MIT (or should be included
|
||||
// as LICENSE.txt within the associated archive or repository).
|
||||
|
||||
// ============================================================================
|
||||
|
||||
#if ( JAMBU_RV64_TYPE2 )
|
||||
.macro jambu.block.0 rd, rs1, rs2
|
||||
.insn r CUSTOM_3, 7, (32* 1), \rd, \rs1, \rs2
|
||||
.endm
|
||||
.macro jambu.block.1 rd, rs1, rs2
|
||||
.insn r CUSTOM_3, 7, (33* 1), \rd, \rs1, \rs2
|
||||
.endm
|
||||
.macro jambu.block.2 rd, rs1, rs2
|
||||
.insn r CUSTOM_3, 7, (34* 1), \rd, \rs1, \rs2
|
||||
.endm
|
||||
.macro jambu.block.3 rd, rs1, rs2
|
||||
.insn r CUSTOM_3, 7, (35* 1), \rd, \rs1, \rs2
|
||||
.endm
|
||||
#endif
|
||||
|
||||
// ============================================================================
|
36
lwc/src/jambu/fpga-scan.py
Normal file
36
lwc/src/jambu/fpga-scan.py
Normal file
@@ -0,0 +1,36 @@
|
||||
# Copyright (C) 2021 SCARV project <info@scarv.org>
|
||||
#
|
||||
# Use of this source code is restricted per the MIT license, a copy of which
|
||||
# can be found at https://opensource.org/licenses/MIT (or should be included
|
||||
# as LICENSE.txt within the associated archive or repository).
|
||||
|
||||
import driver, itertools
|
||||
|
||||
# =============================================================================
|
||||
|
||||
def rv32( args ) :
|
||||
if ( args.prog ) :
|
||||
driver.program_fpga( args, 'jambu', 'rv32', 'xalu' )
|
||||
if ( args.nist ) :
|
||||
CONF = [ 'DRIVER_BYPASS_TEST' ]
|
||||
# driver.run( args, 'jambu', CONF, 'rv32', 'nist', NIST_IMP = 'ref' )
|
||||
driver.run( args, 'jambu', CONF, 'rv32', 'nist', NIST_IMP = 'opt' )
|
||||
|
||||
for TYPE in [ 'JAMBU_RV32_TYPE1', 'JAMBU_RV32_TYPE2', 'JAMBU_RV32_TYPE3' ] :
|
||||
CONF = [ TYPE ]
|
||||
# there is only unrolled implementation for TinyJAMBU on rv32
|
||||
CONF += [ 'JAMBU_RV32_UNROLL' ]
|
||||
CONF += [ 'DRIVER_BYPASS_TEST' ]
|
||||
driver.run( args, 'jambu', CONF, 'rv32', 'rv32', NIST_IMP = 'opt' )
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
def rv64( args ) :
|
||||
pass
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
if ( __name__ == '__main__' ) :
|
||||
driver.main( rv32, rv64 )
|
||||
|
||||
# =============================================================================
|
145
lwc/src/jambu/imp/rv32/jambu_imp.S
Normal file
145
lwc/src/jambu/imp/rv32/jambu_imp.S
Normal file
@@ -0,0 +1,145 @@
|
||||
#include "zbkb.h"
|
||||
#include "zbkx.h"
|
||||
#include "ise.h"
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Register Allocation
|
||||
// (use caller-saved registers to save push/pop instructions)
|
||||
//
|
||||
// a0, a1: the address of state, key, resp.
|
||||
// a2: the number of steps
|
||||
// a3-a6: state
|
||||
// a7, t5, t6, a1: key
|
||||
// t0-t4: temp registers
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
// prologue + epilogue
|
||||
|
||||
.macro JAMBU_PROLOGUE
|
||||
.endm
|
||||
|
||||
.macro JAMBU_EPILOGUE
|
||||
ret
|
||||
.endm
|
||||
|
||||
|
||||
// load state/key + store state
|
||||
|
||||
.macro JAMBU_LDSTATE addr, s0, s1, s2, s3
|
||||
lw \s0, 0(\addr)
|
||||
lw \s1, 4(\addr)
|
||||
lw \s2, 8(\addr)
|
||||
lw \s3, 12(\addr)
|
||||
.endm
|
||||
|
||||
.macro JAMBU_STSTATE s0, s1, s2, s3
|
||||
sw \s0, 0(a0)
|
||||
sw \s1, 4(a0)
|
||||
sw \s2, 8(a0)
|
||||
sw \s3, 12(a0)
|
||||
.endm
|
||||
|
||||
|
||||
// layers
|
||||
|
||||
.macro JAMBU_ROUND_STEP0 r0, s0, s1, t0
|
||||
#if (JAMBU_RV32_TYPE2)
|
||||
jambu.fsri \r0, \s0, \s1, 15
|
||||
#elif (JAMBU_RV32_TYPE3)
|
||||
jambu.fsr.15 \r0, \s0, \s1
|
||||
#else
|
||||
srli \r0, \s0, 15
|
||||
slli \t0, \s1, 17
|
||||
or \r0, \r0, \t0
|
||||
#endif
|
||||
.endm
|
||||
|
||||
.macro JAMBU_ROUND_STEP1 r0, s0, s1, t0
|
||||
#if (JAMBU_RV32_TYPE2)
|
||||
jambu.fsri \r0, \s0, \s1, 6
|
||||
#elif (JAMBU_RV32_TYPE3)
|
||||
jambu.fsr.6 \r0, \s0, \s1
|
||||
#else
|
||||
srli \r0, \s0, 6
|
||||
slli \t0, \s1, 26
|
||||
or \r0, \r0, \t0
|
||||
#endif
|
||||
.endm
|
||||
|
||||
.macro JAMBU_ROUND_STEP2 r0, s0, s1, t0
|
||||
#if (JAMBU_RV32_TYPE2)
|
||||
jambu.fsri \r0, \s0, \s1, 21
|
||||
#elif (JAMBU_RV32_TYPE3)
|
||||
jambu.fsr.21 \r0, \s0, \s1
|
||||
#else
|
||||
srli \r0, \s0, 21
|
||||
slli \t0, \s1, 11
|
||||
or \r0, \r0, \t0
|
||||
#endif
|
||||
.endm
|
||||
|
||||
.macro JAMBU_ROUND_STEP3 r0, s0, s1, t0
|
||||
#if (JAMBU_RV32_TYPE2)
|
||||
jambu.fsri \r0, \s0, \s1, 27
|
||||
# elif (JAMBU_RV32_TYPE3)
|
||||
jambu.fsr.27 \r0, \s0, \s1
|
||||
#else
|
||||
srli \r0, \s0, 27
|
||||
slli \t0, \s1, 5
|
||||
or \r0, \r0, \t0
|
||||
#endif
|
||||
.endm
|
||||
|
||||
.macro JAMBU_ROUND_STEP4 s0, k0, t1, t2, t3, t4
|
||||
and \t2, \t2, \t3
|
||||
xnor \t2, \t1, \t2
|
||||
xor \t2, \t2, \t4
|
||||
xor \t2, \t2, \k0
|
||||
xor \s0, \s0, \t2
|
||||
.endm
|
||||
|
||||
|
||||
// operations in each round
|
||||
|
||||
.macro JMABU_ROUND s0, s1, s2, s3, k0, t1, t2, t3, t4, t5
|
||||
JAMBU_ROUND_STEP0 \t1, \s1, \s2, \t5
|
||||
JAMBU_ROUND_STEP1 \t2, \s2, \s3, \t5
|
||||
JAMBU_ROUND_STEP2 \t3, \s2, \s3, \t5
|
||||
JAMBU_ROUND_STEP3 \t4, \s2, \s3, \t5
|
||||
JAMBU_ROUND_STEP4 \s0, \k0, \t1, \t2, \t3, \t4
|
||||
.endm
|
||||
|
||||
|
||||
// state_update (P640, P1024)
|
||||
|
||||
.section .text
|
||||
|
||||
.global state_update
|
||||
|
||||
state_update:
|
||||
JAMBU_PROLOGUE
|
||||
JAMBU_LDSTATE a0, a3, a4, a5, a6
|
||||
JAMBU_LDSTATE a1, a7, t5, t6, a1
|
||||
//
|
||||
.rept 5
|
||||
JMABU_ROUND a3, a4, a5, a6, a7, t1, t2, t3, t4, t0
|
||||
JMABU_ROUND a4, a5, a6, a3, t5, t1, t2, t3, t4, t0
|
||||
JMABU_ROUND a5, a6, a3, a4, t6, t1, t2, t3, t4, t0
|
||||
JMABU_ROUND a6, a3, a4, a5, a1, t1, t2, t3, t4, t0
|
||||
.endr
|
||||
//
|
||||
addi a2, a2, -640 // check it is P640 or P1024
|
||||
beqz a2, JAMBU_END // if a2 == 640, then goto JAMBU_END
|
||||
//
|
||||
.rept 3
|
||||
JMABU_ROUND a3, a4, a5, a6, a7, t1, t2, t3, t4, t0
|
||||
JMABU_ROUND a4, a5, a6, a3, t5, t1, t2, t3, t4, t0
|
||||
JMABU_ROUND a5, a6, a3, a4, t6, t1, t2, t3, t4, t0
|
||||
JMABU_ROUND a6, a3, a4, a5, a1, t1, t2, t3, t4, t0
|
||||
.endr
|
||||
//
|
||||
JAMBU_END:
|
||||
JAMBU_STSTATE a3, a4, a5, a6
|
||||
JAMBU_EPILOGUE
|
1
lwc/src/jambu/nist.url
Normal file
1
lwc/src/jambu/nist.url
Normal file
@@ -0,0 +1 @@
|
||||
https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/documents/finalist-round/updated-submissions/tinyjambu.zip
|
3
lwc/src/jambu/nist.zip
Normal file
3
lwc/src/jambu/nist.zip
Normal file
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:289ef4421dbf0008cc36a8cb1ea7b84b7a5e6fbd862f0d49ded3407379cf6c43
|
||||
size 871275
|
3
lwc/src/jambu/nist/Documents/TinyJAMBU_v2_17May2021.pdf
Normal file
3
lwc/src/jambu/nist/Documents/TinyJAMBU_v2_17May2021.pdf
Normal file
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:a5f3b677be97696b9575016de40261b0ca11039dd45d79ec891fc35b68b49d96
|
||||
size 1307095
|
3
lwc/src/jambu/nist/Documents/Tweak_17May2021.pdf
Normal file
3
lwc/src/jambu/nist/Documents/Tweak_17May2021.pdf
Normal file
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:29ab0c72e87a9bbaa1a1bee969c462aa6a7dcb0a5cc9b51ae2499f56c5bff676
|
||||
size 143105
|
3
lwc/src/jambu/nist/Documents/coversheet.pdf
Normal file
3
lwc/src/jambu/nist/Documents/coversheet.pdf
Normal file
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:9c9c33eceff69413f0734bec72c2dc857f001ac316ffc4fb9b74f111a8451a76
|
||||
size 45506
|
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,5 @@
|
||||
#define CRYPTO_KEYBYTES 16
|
||||
#define CRYPTO_NSECBYTES 0
|
||||
#define CRYPTO_NPUBBYTES 12
|
||||
#define CRYPTO_ABYTES 8
|
||||
#define CRYPTO_NOOVERLAP 1
|
@@ -0,0 +1,219 @@
|
||||
/*
|
||||
TinyJAMBU-128: 128-bit key, 96-bit IV
|
||||
Optimized implementation
|
||||
The state consists of four 32-bit registers
|
||||
state[3] || state[2] || state[1] || state[0]
|
||||
|
||||
Implemented by: Hongjun Wu
|
||||
*/
|
||||
|
||||
|
||||
#include "crypto_aead.h"
|
||||
|
||||
#define FrameBitsIV 0x10
|
||||
#define FrameBitsAD 0x30
|
||||
#define FrameBitsPC 0x50 //Framebits for plaintext/ciphertext
|
||||
#define FrameBitsFinalization 0x70
|
||||
|
||||
#define NROUND1 128*5
|
||||
#define NROUND2 128*8
|
||||
|
||||
#if !defined(LWISE)
|
||||
/*optimized state update function*/
|
||||
void state_update(unsigned int *state, const unsigned char *key, unsigned int number_of_steps)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int t1, t2, t3, t4;
|
||||
|
||||
//in each iteration, we compute 128 rounds of the state update function.
|
||||
for (i = 0; i < number_of_steps; i = i + 128)
|
||||
{
|
||||
t1 = (state[1] >> 15) | (state[2] << 17); // 47 = 1*32+15
|
||||
t2 = (state[2] >> 6) | (state[3] << 26); // 47 + 23 = 70 = 2*32 + 6
|
||||
t3 = (state[2] >> 21) | (state[3] << 11); // 47 + 23 + 15 = 85 = 2*32 + 21
|
||||
t4 = (state[2] >> 27) | (state[3] << 5); // 47 + 23 + 15 + 6 = 91 = 2*32 + 27
|
||||
state[0] ^= t1 ^ (~(t2 & t3)) ^ t4 ^ ((unsigned int*)key)[0];
|
||||
|
||||
t1 = (state[2] >> 15) | (state[3] << 17);
|
||||
t2 = (state[3] >> 6) | (state[0] << 26);
|
||||
t3 = (state[3] >> 21) | (state[0] << 11);
|
||||
t4 = (state[3] >> 27) | (state[0] << 5);
|
||||
state[1] ^= t1 ^ (~(t2 & t3)) ^ t4 ^ ((unsigned int*)key)[1];
|
||||
|
||||
t1 = (state[3] >> 15) | (state[0] << 17);
|
||||
t2 = (state[0] >> 6) | (state[1] << 26);
|
||||
t3 = (state[0] >> 21) | (state[1] << 11);
|
||||
t4 = (state[0] >> 27) | (state[1] << 5);
|
||||
state[2] ^= t1 ^ (~(t2 & t3)) ^ t4 ^ ((unsigned int*)key)[2];
|
||||
|
||||
t1 = (state[0] >> 15) | (state[1] << 17);
|
||||
t2 = (state[1] >> 6) | (state[2] << 26);
|
||||
t3 = (state[1] >> 21) | (state[2] << 11);
|
||||
t4 = (state[1] >> 27) | (state[2] << 5);
|
||||
state[3] ^= t1 ^ (~(t2 & t3)) ^ t4 ^ ((unsigned int*)key)[3];
|
||||
}
|
||||
}
|
||||
#else
|
||||
extern void state_update(void *state, const void *key, unsigned int number_of_steps);
|
||||
#endif
|
||||
|
||||
// The initialization
|
||||
/* The input to initialization is the 128-bit key; 96-bit IV;*/
|
||||
void initialization(const unsigned char *key, const unsigned char *iv, unsigned int *state)
|
||||
{
|
||||
int i;
|
||||
|
||||
//initialize the state as 0
|
||||
for (i = 0; i < 4; i++) state[i] = 0;
|
||||
|
||||
//update the state with the key
|
||||
state_update(state, key, NROUND2);
|
||||
|
||||
//introduce IV into the state
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
state[1] ^= FrameBitsIV;
|
||||
state_update(state, key, NROUND1);
|
||||
state[3] ^= ((unsigned int*)iv)[i];
|
||||
}
|
||||
}
|
||||
|
||||
//process the associated data
|
||||
void process_ad(const unsigned char *k, const unsigned char *ad, unsigned long long adlen, unsigned int *state)
|
||||
{
|
||||
unsigned long long i;
|
||||
unsigned int j;
|
||||
|
||||
for (i = 0; i < (adlen >> 2); i++)
|
||||
{
|
||||
state[1] ^= FrameBitsAD;
|
||||
state_update(state, k, NROUND1);
|
||||
state[3] ^= ((unsigned int*)ad)[i];
|
||||
}
|
||||
|
||||
// if adlen is not a multiple of 4, we process the remaining bytes
|
||||
if ((adlen & 3) > 0)
|
||||
{
|
||||
state[1] ^= FrameBitsAD;
|
||||
state_update(state, k, NROUND1);
|
||||
for (j = 0; j < (adlen & 3); j++) ((unsigned char*)state)[12 + j] ^= ad[(i << 2) + j];
|
||||
state[1] ^= adlen & 3;
|
||||
}
|
||||
}
|
||||
|
||||
//encrypt plaintext
|
||||
int crypto_aead_encrypt(
|
||||
unsigned char *c, unsigned long long *clen,
|
||||
const unsigned char *m, unsigned long long mlen,
|
||||
const unsigned char *ad, unsigned long long adlen,
|
||||
const unsigned char *nsec,
|
||||
const unsigned char *npub,
|
||||
const unsigned char *k
|
||||
)
|
||||
{
|
||||
unsigned long long i;
|
||||
unsigned int j;
|
||||
unsigned char mac[8];
|
||||
unsigned int state[4];
|
||||
|
||||
//initialization stage
|
||||
initialization(k, npub, state);
|
||||
|
||||
//process the associated data
|
||||
process_ad(k, ad, adlen, state);
|
||||
|
||||
//process the plaintext
|
||||
for (i = 0; i < (mlen >> 2); i++)
|
||||
{
|
||||
state[1] ^= FrameBitsPC;
|
||||
state_update(state, k, NROUND2);
|
||||
state[3] ^= ((unsigned int*)m)[i];
|
||||
((unsigned int*)c)[i] = state[2] ^ ((unsigned int*)m)[i];
|
||||
}
|
||||
// if mlen is not a multiple of 4, we process the remaining bytes
|
||||
if ((mlen & 3) > 0)
|
||||
{
|
||||
state[1] ^= FrameBitsPC;
|
||||
state_update(state, k, NROUND2);
|
||||
for (j = 0; j < (mlen & 3); j++)
|
||||
{
|
||||
((unsigned char*)state)[12 + j] ^= m[(i << 2) + j];
|
||||
c[(i << 2) + j] = ((unsigned char*)state)[8 + j] ^ m[(i << 2) + j];
|
||||
}
|
||||
state[1] ^= mlen & 3;
|
||||
}
|
||||
|
||||
//finalization stage, we assume that the tag length is 8 bytes
|
||||
state[1] ^= FrameBitsFinalization;
|
||||
state_update(state, k, NROUND2);
|
||||
((unsigned int*)mac)[0] = state[2];
|
||||
|
||||
state[1] ^= FrameBitsFinalization;
|
||||
state_update(state, k, NROUND1);
|
||||
((unsigned int*)mac)[1] = state[2];
|
||||
|
||||
*clen = mlen + 8;
|
||||
for (j = 0; j < 8; j++) c[mlen+j] = mac[j];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//decrypt a message
|
||||
int crypto_aead_decrypt(
|
||||
unsigned char *m, unsigned long long *mlen,
|
||||
unsigned char *nsec,
|
||||
const unsigned char *c, unsigned long long clen,
|
||||
const unsigned char *ad, unsigned long long adlen,
|
||||
const unsigned char *npub,
|
||||
const unsigned char *k
|
||||
)
|
||||
{
|
||||
unsigned long long i;
|
||||
unsigned int j, check = 0;
|
||||
unsigned char mac[8];
|
||||
unsigned int state[4];
|
||||
|
||||
*mlen = clen - 8;
|
||||
|
||||
//initialization stage
|
||||
initialization(k, npub, state);
|
||||
|
||||
//process the associated data
|
||||
process_ad(k, ad, adlen, state);
|
||||
|
||||
//process the ciphertext
|
||||
for (i = 0; i < (*mlen >> 2); i++)
|
||||
{
|
||||
state[1] ^= FrameBitsPC;
|
||||
state_update(state, k, NROUND2);
|
||||
((unsigned int*)m)[i] = state[2] ^ ((unsigned int*)c)[i];
|
||||
state[3] ^= ((unsigned int*)m)[i];
|
||||
}
|
||||
// if mlen is not a multiple of 4, we process the remaining bytes
|
||||
if ((*mlen & 3) > 0)
|
||||
{
|
||||
state[1] ^= FrameBitsPC;
|
||||
state_update(state, k, NROUND2);
|
||||
for (j = 0; j < (*mlen & 3); j++)
|
||||
{
|
||||
m[(i << 2) + j] = c[(i << 2) + j] ^ ((unsigned char*)state)[8 + j];
|
||||
((unsigned char*)state)[12 + j] ^= m[(i << 2) + j];
|
||||
}
|
||||
state[1] ^= *mlen & 3;
|
||||
}
|
||||
|
||||
//finalization stage, we assume that the tag length is 8 bytes
|
||||
state[1] ^= FrameBitsFinalization;
|
||||
state_update(state, k, NROUND2);
|
||||
((unsigned int*)mac)[0] = state[2];
|
||||
|
||||
state[1] ^= FrameBitsFinalization;
|
||||
state_update(state, k, NROUND1);
|
||||
((unsigned int*)mac)[1] = state[2];
|
||||
|
||||
//verification of the authentication tag
|
||||
for (j = 0; j < 8; j++) { check |= (mac[j] ^ c[clen - 8 + j]); }
|
||||
if (check == 0) return 0;
|
||||
else return -1;
|
||||
}
|
||||
|
@@ -0,0 +1,5 @@
|
||||
#define CRYPTO_KEYBYTES 16
|
||||
#define CRYPTO_NSECBYTES 0
|
||||
#define CRYPTO_NPUBBYTES 12
|
||||
#define CRYPTO_ABYTES 8
|
||||
#define CRYPTO_NOOVERLAP 1
|
@@ -0,0 +1,200 @@
|
||||
/*
|
||||
TinyJAMBU-128: 128-bit key, 96-bit IV
|
||||
Reference implementation for 32-bit CPU
|
||||
The state consists of four 32-bit registers
|
||||
state[3] || state[2] || state[1] || state[0]
|
||||
|
||||
Implemented by: Hongjun Wu
|
||||
*/
|
||||
|
||||
#include "crypto_aead.h"
|
||||
|
||||
#define FrameBitsIV 0x10
|
||||
#define FrameBitsAD 0x30
|
||||
#define FrameBitsPC 0x50 //Framebits for plaintext/ciphertext
|
||||
#define FrameBitsFinalization 0x70
|
||||
|
||||
#define NROUND1 128*5
|
||||
#define NROUND2 128*8
|
||||
|
||||
#if !defined(LWISE)
|
||||
/*no-optimized date update function*/
|
||||
void state_update(unsigned int *state, const unsigned char *key, unsigned int number_of_steps)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int t1, t2, t3, t4, feedback;
|
||||
for (i = 0; i < (number_of_steps >> 5); i++)
|
||||
{
|
||||
t1 = (state[1] >> 15) | (state[2] << 17); // 47 = 1*32+15
|
||||
t2 = (state[2] >> 6) | (state[3] << 26); // 47 + 23 = 70 = 2*32 + 6
|
||||
t3 = (state[2] >> 21) | (state[3] << 11); // 47 + 23 + 15 = 85 = 2*32 + 21
|
||||
t4 = (state[2] >> 27) | (state[3] << 5); // 47 + 23 + 15 + 6 = 91 = 2*32 + 27
|
||||
feedback = state[0] ^ t1 ^ (~(t2 & t3)) ^ t4 ^ ((unsigned int*)key)[i & 3];
|
||||
// shift 32 bit positions
|
||||
state[0] = state[1]; state[1] = state[2]; state[2] = state[3];
|
||||
state[3] = feedback ;
|
||||
}
|
||||
}
|
||||
#else
|
||||
extern void state_update(void *state, const void *key, unsigned int number_of_steps);
|
||||
#endif
|
||||
|
||||
// The initialization
|
||||
/* The input to initialization is the 128-bit key; 96-bit IV;*/
|
||||
void initialization(const unsigned char *key, const unsigned char *iv, unsigned int *state)
|
||||
{
|
||||
int i;
|
||||
|
||||
//initialize the state as 0
|
||||
for (i = 0; i < 4; i++) state[i] = 0;
|
||||
|
||||
//update the state with the key
|
||||
state_update(state, key, NROUND2);
|
||||
|
||||
//introduce IV into the state
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
state[1] ^= FrameBitsIV;
|
||||
state_update(state, key, NROUND1);
|
||||
state[3] ^= ((unsigned int*)iv)[i];
|
||||
}
|
||||
}
|
||||
|
||||
//process the associated data
|
||||
void process_ad(const unsigned char *k, const unsigned char *ad, unsigned long long adlen, unsigned int *state)
|
||||
{
|
||||
unsigned long long i;
|
||||
unsigned int j;
|
||||
|
||||
for (i = 0; i < (adlen >> 2); i++)
|
||||
{
|
||||
state[1] ^= FrameBitsAD;
|
||||
state_update(state, k, NROUND1);
|
||||
state[3] ^= ((unsigned int*)ad)[i];
|
||||
}
|
||||
|
||||
// if adlen is not a multiple of 4, we process the remaining bytes
|
||||
if ((adlen & 3) > 0)
|
||||
{
|
||||
state[1] ^= FrameBitsAD;
|
||||
state_update(state, k, NROUND1);
|
||||
for (j = 0; j < (adlen & 3); j++) ((unsigned char*)state)[12 + j] ^= ad[(i << 2) + j];
|
||||
state[1] ^= adlen & 3;
|
||||
}
|
||||
}
|
||||
|
||||
//encrypt plaintext
|
||||
int crypto_aead_encrypt(
|
||||
unsigned char *c,unsigned long long *clen,
|
||||
const unsigned char *m,unsigned long long mlen,
|
||||
const unsigned char *ad,unsigned long long adlen,
|
||||
const unsigned char *nsec,
|
||||
const unsigned char *npub,
|
||||
const unsigned char *k
|
||||
)
|
||||
{
|
||||
unsigned long long i;
|
||||
unsigned int j;
|
||||
unsigned char mac[8];
|
||||
unsigned int state[4];
|
||||
|
||||
//initialization stage
|
||||
initialization(k, npub, state);
|
||||
|
||||
//process the associated data
|
||||
process_ad(k, ad, adlen, state);
|
||||
|
||||
//process the plaintext
|
||||
for (i = 0; i < (mlen >> 2); i++)
|
||||
{
|
||||
state[1] ^= FrameBitsPC;
|
||||
state_update(state, k, NROUND2);
|
||||
state[3] ^= ((unsigned int*)m)[i];
|
||||
((unsigned int*)c)[i] = state[2] ^ ((unsigned int*)m)[i];
|
||||
}
|
||||
// if mlen is not a multiple of 4, we process the remaining bytes
|
||||
if ((mlen & 3) > 0)
|
||||
{
|
||||
state[1] ^= FrameBitsPC;
|
||||
state_update(state, k, NROUND2);
|
||||
for (j = 0; j < (mlen & 3); j++)
|
||||
{
|
||||
((unsigned char*)state)[12 + j] ^= m[(i << 2) + j];
|
||||
c[(i << 2) + j] = ((unsigned char*)state)[8 + j] ^ m[(i << 2) + j];
|
||||
}
|
||||
state[1] ^= mlen & 3;
|
||||
}
|
||||
|
||||
//finalization stage, we assume that the tag length is 8 bytes
|
||||
state[1] ^= FrameBitsFinalization;
|
||||
state_update(state, k, NROUND2);
|
||||
((unsigned int*)mac)[0] = state[2];
|
||||
|
||||
state[1] ^= FrameBitsFinalization;
|
||||
state_update(state, k, NROUND1);
|
||||
((unsigned int*)mac)[1] = state[2];
|
||||
|
||||
*clen = mlen + 8;
|
||||
for (j = 0; j < 8; j++) c[mlen+j] = mac[j];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//decrypt a message
|
||||
int crypto_aead_decrypt(
|
||||
unsigned char *m,unsigned long long *mlen,
|
||||
unsigned char *nsec,
|
||||
const unsigned char *c,unsigned long long clen,
|
||||
const unsigned char *ad,unsigned long long adlen,
|
||||
const unsigned char *npub,
|
||||
const unsigned char *k
|
||||
)
|
||||
{
|
||||
unsigned long long i;
|
||||
unsigned int j, check = 0;
|
||||
unsigned char mac[8];
|
||||
unsigned int state[4];
|
||||
|
||||
*mlen = clen - 8;
|
||||
|
||||
//initialization stage
|
||||
initialization(k, npub, state);
|
||||
|
||||
//process the associated data
|
||||
process_ad(k, ad, adlen, state);
|
||||
|
||||
//process the ciphertext
|
||||
for (i = 0; i < (*mlen >> 2); i++)
|
||||
{
|
||||
state[1] ^= FrameBitsPC;
|
||||
state_update(state, k, NROUND2);
|
||||
((unsigned int*)m)[i] = state[2] ^ ((unsigned int*)c)[i];
|
||||
state[3] ^= ((unsigned int*)m)[i];
|
||||
}
|
||||
// if mlen is not a multiple of 4, we process the remaining bytes
|
||||
if ((*mlen & 3) > 0)
|
||||
{
|
||||
state[1] ^= FrameBitsPC;
|
||||
state_update(state, k, NROUND2);
|
||||
for (j = 0; j < (*mlen & 3); j++)
|
||||
{
|
||||
m[(i << 2) + j] = c[(i << 2) + j] ^ ((unsigned char*)state)[8 + j];
|
||||
((unsigned char*)state)[12 + j] ^= m[(i << 2) + j];
|
||||
}
|
||||
state[1] ^= *mlen & 3;
|
||||
}
|
||||
|
||||
//finalization stage, we assume that the tag length is 8 bytes
|
||||
state[1] ^= FrameBitsFinalization;
|
||||
state_update(state, k, NROUND2);
|
||||
((unsigned int*)mac)[0] = state[2];
|
||||
|
||||
state[1] ^= FrameBitsFinalization;
|
||||
state_update(state, k, NROUND1);
|
||||
((unsigned int*)mac)[1] = state[2];
|
||||
|
||||
//verification of the authentication tag
|
||||
for (j = 0; j < 8; j++) { check |= (mac[j] ^ c[clen - 8 + j]); }
|
||||
if (check == 0) return 0;
|
||||
else return -1;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,5 @@
|
||||
#define CRYPTO_KEYBYTES 24
|
||||
#define CRYPTO_NSECBYTES 0
|
||||
#define CRYPTO_NPUBBYTES 12
|
||||
#define CRYPTO_ABYTES 8
|
||||
#define CRYPTO_NOOVERLAP 1
|
@@ -0,0 +1,218 @@
|
||||
/*
|
||||
TinyJAMBU-192: 192-bit key, 96-bit IV
|
||||
Optimized Implementation for 32-bit processor
|
||||
The state consists of four 32-bit registers
|
||||
state[3] || state[2] || state[1] || state[0]
|
||||
|
||||
Implemented by Hongjun Wu
|
||||
*/
|
||||
|
||||
#include "crypto_aead.h"
|
||||
|
||||
#define FrameBitsIV 0x10
|
||||
#define FrameBitsAD 0x30
|
||||
#define FrameBitsPC 0x50 //Framebits for plaintext/ciphertext
|
||||
#define FrameBitsFinalization 0x70
|
||||
|
||||
#define NROUND1 128*5
|
||||
#define NROUND2 128*9
|
||||
|
||||
/*optimized state update function*/
|
||||
void state_update(unsigned int *state, const unsigned char *key, unsigned int number_of_steps)
|
||||
{
|
||||
unsigned int i, j;
|
||||
unsigned int t1, t2, t3, t4;
|
||||
|
||||
//in each iteration, we compute 128 rounds of the state update function.
|
||||
for (i = 0, j = 0; i < number_of_steps; i = i + 128)
|
||||
{
|
||||
t1 = (state[1] >> 15) | (state[2] << 17); // 47 = 1*32+15
|
||||
t2 = (state[2] >> 6) | (state[3] << 26); // 47 + 23 = 70 = 2*32 + 6
|
||||
t3 = (state[2] >> 21) | (state[3] << 11); // 47 + 23 + 15 = 85 = 2*32 + 21
|
||||
t4 = (state[2] >> 27) | (state[3] << 5); // 47 + 23 + 15 + 6 = 91 = 2*32 + 27
|
||||
state[0] ^= t1 ^ (~(t2 & t3)) ^ t4 ^ ((unsigned int*)key)[j];
|
||||
j = j + 1;
|
||||
|
||||
t1 = (state[2] >> 15) | (state[3] << 17);
|
||||
t2 = (state[3] >> 6) | (state[0] << 26);
|
||||
t3 = (state[3] >> 21) | (state[0] << 11);
|
||||
t4 = (state[3] >> 27) | (state[0] << 5);
|
||||
state[1] ^= t1 ^ (~(t2 & t3)) ^ t4 ^ ((unsigned int*)key)[j];
|
||||
j = j + 1; if (j == 6) j = 0; // it is to compute j = (j+1)%6
|
||||
|
||||
t1 = (state[3] >> 15) | (state[0] << 17);
|
||||
t2 = (state[0] >> 6) | (state[1] << 26);
|
||||
t3 = (state[0] >> 21) | (state[1] << 11);
|
||||
t4 = (state[0] >> 27) | (state[1] << 5);
|
||||
state[2] ^= t1 ^ (~(t2 & t3)) ^ t4 ^ ((unsigned int*)key)[j];
|
||||
j = j + 1;
|
||||
|
||||
t1 = (state[0] >> 15) | (state[1] << 17);
|
||||
t2 = (state[1] >> 6) | (state[2] << 26);
|
||||
t3 = (state[1] >> 21) | (state[2] << 11);
|
||||
t4 = (state[1] >> 27) | (state[2] << 5);
|
||||
state[3] ^= t1 ^ (~(t2 & t3)) ^ t4 ^ ((unsigned int*)key)[j];
|
||||
j = j + 1; if (j == 6) j = 0; // it is to compute j = (j+1)%6
|
||||
}
|
||||
}
|
||||
|
||||
// The initialization
|
||||
/* The input to initialization is the 192-bit key; 96-bit IV;*/
|
||||
void initialization(const unsigned char *key, const unsigned char *iv, unsigned int *state)
|
||||
{
|
||||
int i;
|
||||
|
||||
//initialize the state as 0
|
||||
for (i = 0; i < 4; i++) state[i] = 0;
|
||||
|
||||
//update the state with the key
|
||||
state_update(state, key, NROUND2);
|
||||
|
||||
//introduce IV into the state
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
state[1] ^= FrameBitsIV;
|
||||
state_update(state, key, NROUND1);
|
||||
state[3] ^= ((unsigned int*)iv)[i];
|
||||
}
|
||||
}
|
||||
|
||||
//process the associated data
|
||||
void process_ad(const unsigned char *k, const unsigned char *ad, unsigned long long adlen, unsigned int *state)
|
||||
{
|
||||
unsigned long long i;
|
||||
unsigned int j;
|
||||
|
||||
for (i = 0; i < (adlen >> 2); i++)
|
||||
{
|
||||
state[1] ^= FrameBitsAD;
|
||||
state_update(state, k, NROUND1);
|
||||
state[3] ^= ((unsigned int*)ad)[i];
|
||||
}
|
||||
|
||||
// if adlen is not a multiple of 4, we process the remaining bytes
|
||||
if ((adlen & 3) > 0)
|
||||
{
|
||||
state[1] ^= FrameBitsAD;
|
||||
state_update(state, k, NROUND1);
|
||||
for (j = 0; j < (adlen & 3); j++) ((unsigned char*)state)[12 + j] ^= ad[(i << 2) + j];
|
||||
state[1] ^= adlen & 3;
|
||||
}
|
||||
}
|
||||
|
||||
//encrypt a message
|
||||
int crypto_aead_encrypt(
|
||||
unsigned char *c, unsigned long long *clen,
|
||||
const unsigned char *m, unsigned long long mlen,
|
||||
const unsigned char *ad, unsigned long long adlen,
|
||||
const unsigned char *nsec,
|
||||
const unsigned char *npub,
|
||||
const unsigned char *k
|
||||
)
|
||||
{
|
||||
unsigned long long i;
|
||||
unsigned int j;
|
||||
unsigned char mac[8];
|
||||
unsigned int state[4];
|
||||
|
||||
//initialization stage
|
||||
initialization(k, npub, state);
|
||||
|
||||
//process the associated data
|
||||
process_ad(k, ad, adlen, state);
|
||||
|
||||
//process the plaintext
|
||||
for (i = 0; i < (mlen >> 2); i++)
|
||||
{
|
||||
state[1] ^= FrameBitsPC;
|
||||
state_update(state, k, NROUND2);
|
||||
state[3] ^= ((unsigned int*)m)[i];
|
||||
((unsigned int*)c)[i] = state[2] ^ ((unsigned int*)m)[i];
|
||||
}
|
||||
// if mlen is not a multiple of 4, we process the remaining bytes
|
||||
if ((mlen & 3) > 0)
|
||||
{
|
||||
state[1] ^= FrameBitsPC;
|
||||
state_update(state, k, NROUND2);
|
||||
for (j = 0; j < (mlen & 3); j++)
|
||||
{
|
||||
((unsigned char*)state)[12 + j] ^= m[(i << 2) + j];
|
||||
c[(i << 2) + j] = ((unsigned char*)state)[8 + j] ^ m[(i << 2) + j];
|
||||
}
|
||||
state[1] ^= mlen & 3;
|
||||
}
|
||||
|
||||
//finalization stage, we assume that the tag length is 8 bytes
|
||||
state[1] ^= FrameBitsFinalization;
|
||||
state_update(state, k, NROUND2);
|
||||
((unsigned int*)mac)[0] = state[2];
|
||||
|
||||
state[1] ^= FrameBitsFinalization;
|
||||
state_update(state, k, NROUND1);
|
||||
((unsigned int*)mac)[1] = state[2];
|
||||
|
||||
*clen = mlen + 8;
|
||||
for (j = 0; j < 8; j++) c[mlen+j] = mac[j];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//decrypt a message
|
||||
int crypto_aead_decrypt(
|
||||
unsigned char *m, unsigned long long *mlen,
|
||||
unsigned char *nsec,
|
||||
const unsigned char *c, unsigned long long clen,
|
||||
const unsigned char *ad, unsigned long long adlen,
|
||||
const unsigned char *npub,
|
||||
const unsigned char *k
|
||||
)
|
||||
{
|
||||
unsigned long long i;
|
||||
unsigned int j, check = 0;
|
||||
unsigned char mac[8];
|
||||
unsigned int state[4];
|
||||
|
||||
*mlen = clen - 8;
|
||||
|
||||
//initialization stage
|
||||
initialization(k, npub, state);
|
||||
|
||||
//process the associated data
|
||||
process_ad(k, ad, adlen, state);
|
||||
|
||||
//process the ciphertext
|
||||
for (i = 0; i < (*mlen >> 2); i++)
|
||||
{
|
||||
state[1] ^= FrameBitsPC;
|
||||
state_update(state, k, NROUND2);
|
||||
((unsigned int*)m)[i] = state[2] ^ ((unsigned int*)c)[i];
|
||||
state[3] ^= ((unsigned int*)m)[i];
|
||||
}
|
||||
// if mlen is not a multiple of 4, we process the remaining bytes
|
||||
if ((*mlen & 3) > 0)
|
||||
{
|
||||
state[1] ^= FrameBitsPC;
|
||||
state_update(state, k, NROUND2);
|
||||
for (j = 0; j < (*mlen & 3); j++)
|
||||
{
|
||||
m[(i << 2) + j] = c[(i << 2) + j] ^ ((unsigned char*)state)[8 + j];
|
||||
((unsigned char*)state)[12 + j] ^= m[(i << 2) + j];
|
||||
}
|
||||
state[1] ^= *mlen & 3;
|
||||
}
|
||||
|
||||
|
||||
//finalization stage, we assume that the tag length is 8 bytes
|
||||
state[1] ^= FrameBitsFinalization;
|
||||
state_update(state, k, NROUND2);
|
||||
((unsigned int*)mac)[0] = state[2];
|
||||
|
||||
state[1] ^= FrameBitsFinalization;
|
||||
state_update(state, k, NROUND1);
|
||||
((unsigned int*)mac)[1] = state[2];
|
||||
|
||||
//verification of the authentication tag
|
||||
for (j = 0; j < 8; j++) { check |= (mac[j] ^ c[clen - 8 + j]); }
|
||||
if (check == 0) return 0;
|
||||
else return -1;
|
||||
}
|
@@ -0,0 +1,5 @@
|
||||
#define CRYPTO_KEYBYTES 24
|
||||
#define CRYPTO_NSECBYTES 0
|
||||
#define CRYPTO_NPUBBYTES 12
|
||||
#define CRYPTO_ABYTES 8
|
||||
#define CRYPTO_NOOVERLAP 1
|
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
TinyJAMBU: 192-bit key, 96-bit IV
|
||||
Reference implementation for 32-bit CPU
|
||||
The state consists of four 32-bit registers
|
||||
state[3] || state[2] || state[1] || state[0]
|
||||
|
||||
Implemented by: Hongjun Wu
|
||||
*/
|
||||
|
||||
#include "crypto_aead.h"
|
||||
|
||||
#define FrameBitsIV 0x10
|
||||
#define FrameBitsAD 0x30
|
||||
#define FrameBitsPC 0x50 //Framebits for plaintext/ciphertext
|
||||
#define FrameBitsFinalization 0x70
|
||||
|
||||
#define NROUND1 128*5
|
||||
#define NROUND2 128*9
|
||||
|
||||
/*no-optimized state update function*/
|
||||
void state_update(unsigned int *state, const unsigned char *key, unsigned int number_of_steps)
|
||||
{
|
||||
unsigned int i, j = 0;
|
||||
unsigned int t1, t2, t3, t4, feedback;
|
||||
|
||||
for (i = 0, j = 0; i < (number_of_steps >> 5); i++)
|
||||
{
|
||||
t1 = (state[1] >> 15) | (state[2] << 17); // 47 = 1*32+15
|
||||
t2 = (state[2] >> 6) | (state[3] << 26); // 47 + 23 = 70 = 2*32 + 6
|
||||
t3 = (state[2] >> 21) | (state[3] << 11); // 47 + 23 + 15 = 85 = 2*32 + 21
|
||||
t4 = (state[2] >> 27) | (state[3] << 5); // 47 + 23 + 15 + 6 = 91 = 2*32 + 27
|
||||
feedback = state[0] ^ t1 ^ (~(t2 & t3)) ^ t4 ^ ((unsigned int*)key)[j];
|
||||
// shift 32 bit positions
|
||||
state[0] = state[1]; state[1] = state[2]; state[2] = state[3];
|
||||
state[3] = feedback;
|
||||
|
||||
// compute j = (j+1) % 6, because the key consists of 6 32-bit words
|
||||
j = j + 1;
|
||||
if (j == 6) j = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// The initialization
|
||||
/* The input to initialization is the 192-bit key; 96-bit IV;*/
|
||||
void initialization(const unsigned char *key, const unsigned char *iv, unsigned int *state)
|
||||
{
|
||||
int i;
|
||||
|
||||
//initialize the state as 0
|
||||
for (i = 0; i < 4; i++) state[i] = 0;
|
||||
|
||||
//update the state with the key
|
||||
state_update(state, key, NROUND2);
|
||||
|
||||
//introduce IV into the state
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
state[1] ^= FrameBitsIV;
|
||||
state_update(state, key, NROUND1);
|
||||
state[3] ^= ((unsigned int*)iv)[i];
|
||||
}
|
||||
}
|
||||
|
||||
//process the associated data
|
||||
void process_ad(const unsigned char *k, const unsigned char *ad, unsigned long long adlen, unsigned int *state)
|
||||
{
|
||||
unsigned long long i;
|
||||
unsigned int j;
|
||||
|
||||
for (i = 0; i < (adlen >> 2); i++)
|
||||
{
|
||||
state[1] ^= FrameBitsAD;
|
||||
state_update(state, k, NROUND1);
|
||||
state[3] ^= ((unsigned int*)ad)[i];
|
||||
}
|
||||
|
||||
// if adlen is not a multiple of 4, we process the remaining bytes
|
||||
if ((adlen & 3) > 0)
|
||||
{
|
||||
state[1] ^= FrameBitsAD;
|
||||
state_update(state, k, NROUND1);
|
||||
for (j = 0; j < (adlen & 3); j++) ((unsigned char*)state)[12 + j] ^= ad[(i << 2) + j];
|
||||
state[1] ^= adlen & 3;
|
||||
}
|
||||
}
|
||||
|
||||
//encrypt a message
|
||||
int crypto_aead_encrypt(
|
||||
unsigned char *c,unsigned long long *clen,
|
||||
const unsigned char *m,unsigned long long mlen,
|
||||
const unsigned char *ad,unsigned long long adlen,
|
||||
const unsigned char *nsec,
|
||||
const unsigned char *npub,
|
||||
const unsigned char *k
|
||||
)
|
||||
{
|
||||
unsigned long long i;
|
||||
unsigned int j;
|
||||
unsigned char mac[8];
|
||||
unsigned int state[4];
|
||||
|
||||
//initialization stage
|
||||
initialization(k, npub, state);
|
||||
|
||||
//process the associated data
|
||||
process_ad(k, ad, adlen, state);
|
||||
|
||||
//process the plaintext
|
||||
for (i = 0; i < (mlen >> 2); i++)
|
||||
{
|
||||
state[1] ^= FrameBitsPC;
|
||||
state_update(state, k, NROUND2);
|
||||
state[3] ^= ((unsigned int*)m)[i];
|
||||
((unsigned int*)c)[i] = state[2] ^ ((unsigned int*)m)[i];
|
||||
}
|
||||
// if mlen is not a multiple of 4, we process the remaining bytes
|
||||
if ((mlen & 3) > 0)
|
||||
{
|
||||
state[1] ^= FrameBitsPC;
|
||||
state_update(state, k, NROUND2);
|
||||
for (j = 0; j < (mlen & 3); j++)
|
||||
{
|
||||
((unsigned char*)state)[12 + j] ^= m[(i << 2) + j];
|
||||
c[(i << 2) + j] = ((unsigned char*)state)[8 + j] ^ m[(i << 2) + j];
|
||||
}
|
||||
state[1] ^= mlen & 3;
|
||||
}
|
||||
|
||||
//finalization stage, we assume that the tag length is 8 bytes
|
||||
state[1] ^= FrameBitsFinalization;
|
||||
state_update(state, k, NROUND2);
|
||||
((unsigned int*)mac)[0] = state[2];
|
||||
|
||||
state[1] ^= FrameBitsFinalization;
|
||||
state_update(state, k, NROUND1);
|
||||
((unsigned int*)mac)[1] = state[2];
|
||||
|
||||
*clen = mlen + 8;
|
||||
for (j = 0; j < 8; j++) c[mlen+j] = mac[j];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//decrypt a message
|
||||
int crypto_aead_decrypt(
|
||||
unsigned char *m,unsigned long long *mlen,
|
||||
unsigned char *nsec,
|
||||
const unsigned char *c,unsigned long long clen,
|
||||
const unsigned char *ad,unsigned long long adlen,
|
||||
const unsigned char *npub,
|
||||
const unsigned char *k
|
||||
)
|
||||
{
|
||||
unsigned long long i;
|
||||
unsigned int j, check = 0;
|
||||
unsigned char mac[8];
|
||||
unsigned int state[4];
|
||||
|
||||
*mlen = clen - 8;
|
||||
|
||||
//initialization stage
|
||||
initialization(k, npub, state);
|
||||
|
||||
//process the associated data
|
||||
process_ad(k, ad, adlen, state);
|
||||
|
||||
//process the ciphertext
|
||||
for (i = 0; i < (*mlen >> 2); i++)
|
||||
{
|
||||
state[1] ^= FrameBitsPC;
|
||||
state_update(state, k, NROUND2);
|
||||
((unsigned int*)m)[i] = state[2] ^ ((unsigned int*)c)[i];
|
||||
state[3] ^= ((unsigned int*)m)[i];
|
||||
}
|
||||
// if mlen is not a multiple of 4, we process the remaining bytes
|
||||
if ((*mlen & 3) > 0)
|
||||
{
|
||||
state[1] ^= FrameBitsPC;
|
||||
state_update(state, k, NROUND2);
|
||||
for (j = 0; j < (*mlen & 3); j++)
|
||||
{
|
||||
m[(i << 2) + j] = c[(i << 2) + j] ^ ((unsigned char*)state)[8 + j];
|
||||
((unsigned char*)state)[12 + j] ^= m[(i << 2) + j];
|
||||
}
|
||||
state[1] ^= *mlen & 3;
|
||||
}
|
||||
|
||||
|
||||
//finalization stage, we assume that the tag length is 8 bytes
|
||||
state[1] ^= FrameBitsFinalization;
|
||||
state_update(state, k, NROUND2);
|
||||
((unsigned int*)mac)[0] = state[2];
|
||||
|
||||
state[1] ^= FrameBitsFinalization;
|
||||
state_update(state, k, NROUND1);
|
||||
((unsigned int*)mac)[1] = state[2];
|
||||
|
||||
//verification of the authentication tag
|
||||
for (j = 0; j < 8; j++) { check |= (mac[j] ^ c[clen - 8 + j]); }
|
||||
if (check == 0) return 0;
|
||||
else return -1;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,5 @@
|
||||
#define CRYPTO_KEYBYTES 32
|
||||
#define CRYPTO_NSECBYTES 0
|
||||
#define CRYPTO_NPUBBYTES 12
|
||||
#define CRYPTO_ABYTES 8
|
||||
#define CRYPTO_NOOVERLAP 1
|
@@ -0,0 +1,214 @@
|
||||
/*
|
||||
TinyJAMBU-256: 256-bit key, 96-bit IV
|
||||
Optimized implementation
|
||||
The state consists of four 32-bit registers
|
||||
state[3] || state[2] || state[1] || state[0]
|
||||
|
||||
Implemented by: Hongjun Wu
|
||||
*/
|
||||
|
||||
#include "crypto_aead.h"
|
||||
|
||||
#define FrameBitsIV 0x10
|
||||
#define FrameBitsAD 0x30
|
||||
#define FrameBitsPC 0x50 //Framebits for plaintext/ciphertext
|
||||
#define FrameBitsFinalization 0x70
|
||||
|
||||
#define NROUND1 128*5
|
||||
#define NROUND2 128*10
|
||||
|
||||
/*optimized state update function*/
|
||||
void state_update(unsigned int *state, const unsigned char *key, unsigned int number_of_steps)
|
||||
{
|
||||
unsigned int i, j;
|
||||
unsigned int t1, t2, t3, t4;
|
||||
|
||||
//in each iteration, we compute 128 rounds of the state update function.
|
||||
for (i = 0, j = 0; i < number_of_steps; i = i + 128)
|
||||
{
|
||||
t1 = (state[1] >> 15) | (state[2] << 17); // 47 = 1*32+15
|
||||
t2 = (state[2] >> 6) | (state[3] << 26); // 47 + 23 = 70 = 2*32 + 6
|
||||
t3 = (state[2] >> 21) | (state[3] << 11); // 47 + 23 + 15 = 85 = 2*32 + 21
|
||||
t4 = (state[2] >> 27) | (state[3] << 5); // 47 + 23 + 15 + 6 = 91 = 2*32 + 27
|
||||
state[0] ^= t1 ^ (~(t2 & t3)) ^ t4 ^ ((unsigned int*)key)[(j++)&7];
|
||||
|
||||
t1 = (state[2] >> 15) | (state[3] << 17);
|
||||
t2 = (state[3] >> 6) | (state[0] << 26);
|
||||
t3 = (state[3] >> 21) | (state[0] << 11);
|
||||
t4 = (state[3] >> 27) | (state[0] << 5);
|
||||
state[1] ^= t1 ^ (~(t2 & t3)) ^ t4 ^ ((unsigned int*)key)[(j++) & 7];
|
||||
|
||||
t1 = (state[3] >> 15) | (state[0] << 17);
|
||||
t2 = (state[0] >> 6) | (state[1] << 26);
|
||||
t3 = (state[0] >> 21) | (state[1] << 11);
|
||||
t4 = (state[0] >> 27) | (state[1] << 5);
|
||||
state[2] ^= t1 ^ (~(t2 & t3)) ^ t4 ^ ((unsigned int*)key)[(j++) & 7];
|
||||
|
||||
t1 = (state[0] >> 15) | (state[1] << 17);
|
||||
t2 = (state[1] >> 6) | (state[2] << 26);
|
||||
t3 = (state[1] >> 21) | (state[2] << 11);
|
||||
t4 = (state[1] >> 27) | (state[2] << 5);
|
||||
state[3] ^= t1 ^ (~(t2 & t3)) ^ t4 ^ ((unsigned int*)key)[(j++) & 7];
|
||||
}
|
||||
}
|
||||
|
||||
// The initialization
|
||||
/* The input to initialization is the 128-bit key; 96-bit IV;*/
|
||||
void initialization(const unsigned char *key, const unsigned char *iv, unsigned int *state)
|
||||
{
|
||||
int i;
|
||||
|
||||
//initialize the state as 0
|
||||
for (i = 0; i < 4; i++) state[i] = 0;
|
||||
|
||||
//update the state with the key
|
||||
state_update(state, key, NROUND2);
|
||||
|
||||
//introduce IV into the state
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
state[1] ^= FrameBitsIV;
|
||||
state_update(state, key, NROUND1);
|
||||
state[3] ^= ((unsigned int*)iv)[i];
|
||||
}
|
||||
}
|
||||
|
||||
//process the associated data
|
||||
void process_ad(const unsigned char *k, const unsigned char *ad, unsigned long long adlen, unsigned int *state)
|
||||
{
|
||||
unsigned long long i;
|
||||
unsigned int j;
|
||||
|
||||
for (i = 0; i < (adlen >> 2); i++)
|
||||
{
|
||||
state[1] ^= FrameBitsAD;
|
||||
state_update(state, k, NROUND1);
|
||||
state[3] ^= ((unsigned int*)ad)[i];
|
||||
}
|
||||
|
||||
// if adlen is not a multiple of 4, we process the remaining bytes
|
||||
if ((adlen & 3) > 0)
|
||||
{
|
||||
state[1] ^= FrameBitsAD;
|
||||
state_update(state, k, NROUND1);
|
||||
for (j = 0; j < (adlen & 3); j++) ((unsigned char*)state)[12 + j] ^= ad[(i << 2) + j];
|
||||
state[1] ^= adlen & 3;
|
||||
}
|
||||
}
|
||||
|
||||
//encrypt plaintext
|
||||
int crypto_aead_encrypt(
|
||||
unsigned char *c, unsigned long long *clen,
|
||||
const unsigned char *m, unsigned long long mlen,
|
||||
const unsigned char *ad, unsigned long long adlen,
|
||||
const unsigned char *nsec,
|
||||
const unsigned char *npub,
|
||||
const unsigned char *k
|
||||
)
|
||||
{
|
||||
unsigned long long i;
|
||||
unsigned int j;
|
||||
unsigned char mac[8];
|
||||
unsigned int state[4];
|
||||
|
||||
//initialization stage
|
||||
initialization(k, npub, state);
|
||||
|
||||
//process the associated data
|
||||
process_ad(k, ad, adlen, state);
|
||||
|
||||
//process the plaintext
|
||||
for (i = 0; i < (mlen >> 2); i++)
|
||||
{
|
||||
state[1] ^= FrameBitsPC;
|
||||
state_update(state, k, NROUND2);
|
||||
state[3] ^= ((unsigned int*)m)[i];
|
||||
((unsigned int*)c)[i] = state[2] ^ ((unsigned int*)m)[i];
|
||||
}
|
||||
// if mlen is not a multiple of 4, we process the remaining bytes
|
||||
if ((mlen & 3) > 0)
|
||||
{
|
||||
state[1] ^= FrameBitsPC;
|
||||
state_update(state, k, NROUND2);
|
||||
for (j = 0; j < (mlen & 3); j++)
|
||||
{
|
||||
((unsigned char*)state)[12 + j] ^= m[(i << 2) + j];
|
||||
c[(i << 2) + j] = ((unsigned char*)state)[8 + j] ^ m[(i << 2) + j];
|
||||
}
|
||||
state[1] ^= mlen & 3;
|
||||
}
|
||||
|
||||
//finalization stage, we assume that the tag length is 8 bytes
|
||||
state[1] ^= FrameBitsFinalization;
|
||||
state_update(state, k, NROUND2);
|
||||
((unsigned int*)mac)[0] = state[2];
|
||||
|
||||
state[1] ^= FrameBitsFinalization;
|
||||
state_update(state, k, NROUND1);
|
||||
((unsigned int*)mac)[1] = state[2];
|
||||
|
||||
*clen = mlen + 8;
|
||||
for (j = 0; j < 8; j++) c[mlen+j] = mac[j];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//decrypt a message
|
||||
int crypto_aead_decrypt(
|
||||
unsigned char *m, unsigned long long *mlen,
|
||||
unsigned char *nsec,
|
||||
const unsigned char *c, unsigned long long clen,
|
||||
const unsigned char *ad, unsigned long long adlen,
|
||||
const unsigned char *npub,
|
||||
const unsigned char *k
|
||||
)
|
||||
{
|
||||
unsigned long long i;
|
||||
unsigned int j, check = 0;
|
||||
unsigned char mac[8];
|
||||
unsigned int state[4];
|
||||
|
||||
*mlen = clen - 8;
|
||||
|
||||
//initialization stage
|
||||
initialization(k, npub, state);
|
||||
|
||||
//process the associated data
|
||||
process_ad(k, ad, adlen, state);
|
||||
|
||||
//process the ciphertext
|
||||
for (i = 0; i < (*mlen >> 2); i++)
|
||||
{
|
||||
state[1] ^= FrameBitsPC;
|
||||
state_update(state, k, NROUND2);
|
||||
((unsigned int*)m)[i] = state[2] ^ ((unsigned int*)c)[i];
|
||||
state[3] ^= ((unsigned int*)m)[i];
|
||||
}
|
||||
// if mlen is not a multiple of 4, we process the remaining bytes
|
||||
if ((*mlen & 3) > 0)
|
||||
{
|
||||
state[1] ^= FrameBitsPC;
|
||||
state_update(state, k, NROUND2);
|
||||
for (j = 0; j < (*mlen & 3); j++)
|
||||
{
|
||||
m[(i << 2) + j] = c[(i << 2) + j] ^ ((unsigned char*)state)[8 + j];
|
||||
((unsigned char*)state)[12 + j] ^= m[(i << 2) + j];
|
||||
}
|
||||
state[1] ^= *mlen & 3;
|
||||
}
|
||||
|
||||
//finalization stage, we assume that the tag length is 8 bytes
|
||||
state[1] ^= FrameBitsFinalization;
|
||||
state_update(state, k, NROUND2);
|
||||
((unsigned int*)mac)[0] = state[2];
|
||||
|
||||
state[1] ^= FrameBitsFinalization;
|
||||
state_update(state, k, NROUND1);
|
||||
((unsigned int*)mac)[1] = state[2];
|
||||
|
||||
//verification of the authentication tag
|
||||
for (j = 0; j < 8; j++) { check |= (mac[j] ^ c[clen - 8 + j]); }
|
||||
if (check == 0) return 0;
|
||||
else return -1;
|
||||
}
|
||||
|
@@ -0,0 +1,5 @@
|
||||
#define CRYPTO_KEYBYTES 32
|
||||
#define CRYPTO_NSECBYTES 0
|
||||
#define CRYPTO_NPUBBYTES 12
|
||||
#define CRYPTO_ABYTES 8
|
||||
#define CRYPTO_NOOVERLAP 1
|
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
TinyJAMBU-256: 256-bit key, 96-bit IV
|
||||
Reference Implementation for 32-bit processor
|
||||
The state consists of four 32-bit registers
|
||||
state[3] || state[2] || state[1] || state[0]
|
||||
|
||||
Implemented by Hongjun Wu
|
||||
*/
|
||||
|
||||
#include "crypto_aead.h"
|
||||
|
||||
#define FrameBitsIV 0x10
|
||||
#define FrameBitsAD 0x30
|
||||
#define FrameBitsPC 0x50 //Framebits for plaintext/ciphertext
|
||||
#define FrameBitsFinalization 0x70
|
||||
|
||||
#define NROUND1 128*5
|
||||
#define NROUND2 128*10
|
||||
|
||||
/*non-optimized state update function*/
|
||||
void state_update(unsigned int *state, const unsigned char *key, unsigned int number_of_steps)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int t1, t2, t3, t4, feedback;
|
||||
//in each iteration, we compute 256 steps of the state update function.
|
||||
for (i = 0; i < (number_of_steps >> 5); i++)
|
||||
{
|
||||
t1 = (state[1] >> 15) | (state[2] << 17); // 47 = 1*32+15
|
||||
t2 = (state[2] >> 6) | (state[3] << 26); // 47 + 23 = 70 = 2*32 + 6
|
||||
t3 = (state[2] >> 21) | (state[3] << 11); // 47 + 23 + 15 = 85 = 2*32 + 21
|
||||
t4 = (state[2] >> 27) | (state[3] << 5); // 47 + 23 + 15 + 6 = 91 = 2*32 + 27
|
||||
feedback = state[0] ^ t1 ^ (~(t2 & t3)) ^ t4 ^ ((unsigned int*)key)[i & 7];
|
||||
// shift 32 bit positions
|
||||
state[0] = state[1]; state[1] = state[2]; state[2] = state[3];
|
||||
state[3] = feedback;
|
||||
}
|
||||
}
|
||||
|
||||
// The initialization
|
||||
/* The input to initialization is the 128-bit key; 96-bit IV;*/
|
||||
void initialization(const unsigned char *key, const unsigned char *iv, unsigned int *state)
|
||||
{
|
||||
int i;
|
||||
|
||||
//initialize the state as 0
|
||||
for (i = 0; i < 4; i++) state[i] = 0;
|
||||
|
||||
//update the state with the key
|
||||
state_update(state, key, NROUND2);
|
||||
|
||||
//introduce IV into the state
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
state[1] ^= FrameBitsIV;
|
||||
state_update(state, key, NROUND1);
|
||||
state[3] ^= ((unsigned int*)iv)[i];
|
||||
}
|
||||
}
|
||||
|
||||
//process the associated data
|
||||
void process_ad(const unsigned char *k, const unsigned char *ad, unsigned long long adlen, unsigned int *state)
|
||||
{
|
||||
unsigned long long i;
|
||||
unsigned int j;
|
||||
|
||||
for (i = 0; i < (adlen >> 2); i++)
|
||||
{
|
||||
state[1] ^= FrameBitsAD;
|
||||
state_update(state, k, NROUND1);
|
||||
state[3] ^= ((unsigned int*)ad)[i];
|
||||
}
|
||||
|
||||
// if adlen is not a multiple of 4, we process the remaining bytes
|
||||
if ((adlen & 3) > 0)
|
||||
{
|
||||
state[1] ^= FrameBitsAD;
|
||||
state_update(state, k, NROUND1);
|
||||
for (j = 0; j < (adlen & 3); j++) ((unsigned char*)state)[12 + j] ^= ad[(i << 2) + j];
|
||||
state[1] ^= adlen & 3;
|
||||
}
|
||||
}
|
||||
|
||||
//encrypt a message
|
||||
int crypto_aead_encrypt(
|
||||
unsigned char *c,unsigned long long *clen,
|
||||
const unsigned char *m,unsigned long long mlen,
|
||||
const unsigned char *ad,unsigned long long adlen,
|
||||
const unsigned char *nsec,
|
||||
const unsigned char *npub,
|
||||
const unsigned char *k
|
||||
)
|
||||
{
|
||||
unsigned long long i;
|
||||
unsigned int j;
|
||||
unsigned char mac[8];
|
||||
unsigned int state[4];
|
||||
|
||||
//initialization stage
|
||||
initialization(k, npub, state);
|
||||
|
||||
//process the associated data
|
||||
process_ad(k, ad, adlen, state);
|
||||
|
||||
//process the plaintext
|
||||
for (i = 0; i < (mlen >> 2); i++)
|
||||
{
|
||||
state[1] ^= FrameBitsPC;
|
||||
state_update(state, k, NROUND2);
|
||||
state[3] ^= ((unsigned int*)m)[i];
|
||||
((unsigned int*)c)[i] = state[2] ^ ((unsigned int*)m)[i];
|
||||
}
|
||||
// if mlen is not a multiple of 4, we process the remaining bytes
|
||||
if ((mlen & 3) > 0)
|
||||
{
|
||||
state[1] ^= FrameBitsPC;
|
||||
state_update(state, k, NROUND2);
|
||||
for (j = 0; j < (mlen & 3); j++)
|
||||
{
|
||||
((unsigned char*)state)[12 + j] ^= m[(i << 2) + j];
|
||||
c[(i << 2) + j] = ((unsigned char*)state)[8 + j] ^ m[(i << 2) + j];
|
||||
}
|
||||
state[1] ^= mlen & 3;
|
||||
}
|
||||
|
||||
//finalization stage, we assume that the tag length is 8 bytes
|
||||
state[1] ^= FrameBitsFinalization;
|
||||
state_update(state, k, NROUND2);
|
||||
((unsigned int*)mac)[0] = state[2];
|
||||
|
||||
state[1] ^= FrameBitsFinalization;
|
||||
state_update(state, k, NROUND1);
|
||||
((unsigned int*)mac)[1] = state[2];
|
||||
|
||||
*clen = mlen + 8;
|
||||
for (j = 0; j < 8; j++) c[mlen+j] = mac[j];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//decrypt a message
|
||||
int crypto_aead_decrypt(
|
||||
unsigned char *m,unsigned long long *mlen,
|
||||
unsigned char *nsec,
|
||||
const unsigned char *c,unsigned long long clen,
|
||||
const unsigned char *ad,unsigned long long adlen,
|
||||
const unsigned char *npub,
|
||||
const unsigned char *k
|
||||
)
|
||||
{
|
||||
unsigned long long i;
|
||||
unsigned int j, check = 0;
|
||||
unsigned char mac[8];
|
||||
unsigned int state[4];
|
||||
|
||||
*mlen = clen - 8;
|
||||
|
||||
//initialization stage
|
||||
initialization(k, npub, state);
|
||||
|
||||
//process the associated data
|
||||
process_ad(k, ad, adlen, state);
|
||||
|
||||
//process the ciphertext
|
||||
for (i = 0; i < (*mlen >> 2); i++)
|
||||
{
|
||||
state[1] ^= FrameBitsPC;
|
||||
state_update(state, k, NROUND2);
|
||||
((unsigned int*)m)[i] = state[2] ^ ((unsigned int*)c)[i];
|
||||
state[3] ^= ((unsigned int*)m)[i];
|
||||
}
|
||||
// if mlen is not a multiple of 4, we process the remaining bytes
|
||||
if ((*mlen & 3) > 0)
|
||||
{
|
||||
state[1] ^= FrameBitsPC;
|
||||
state_update(state, k, NROUND2);
|
||||
for (j = 0; j < (*mlen & 3); j++)
|
||||
{
|
||||
m[(i << 2) + j] = c[(i << 2) + j] ^ ((unsigned char*)state)[8 + j];
|
||||
((unsigned char*)state)[12 + j] ^= m[(i << 2) + j];
|
||||
}
|
||||
state[1] ^= *mlen & 3;
|
||||
}
|
||||
|
||||
//finalization stage, we assume that the tag length is 8 bytes
|
||||
state[1] ^= FrameBitsFinalization;
|
||||
state_update(state, k, NROUND2);
|
||||
((unsigned int*)mac)[0] = state[2];
|
||||
|
||||
state[1] ^= FrameBitsFinalization;
|
||||
state_update(state, k, NROUND1);
|
||||
((unsigned int*)mac)[1] = state[2];
|
||||
|
||||
//verification of the authentication tag
|
||||
for (j = 0; j < 8; j++) { check |= (mac[j] ^ c[clen - 8 + j]); }
|
||||
if (check == 0) return 0;
|
||||
else return -1;
|
||||
}
|
48
lwc/src/jambu/scan.py
Normal file
48
lwc/src/jambu/scan.py
Normal file
@@ -0,0 +1,48 @@
|
||||
# Copyright (C) 2021 SCARV project <info@scarv.org>
|
||||
#
|
||||
# Use of this source code is restricted per the MIT license, a copy of which
|
||||
# can be found at https://opensource.org/licenses/MIT (or should be included
|
||||
# as LICENSE.txt within the associated archive or repository).
|
||||
|
||||
import driver, itertools
|
||||
|
||||
# =============================================================================
|
||||
|
||||
def rv32( args ) :
|
||||
if ( args.nist ) :
|
||||
CONF = []
|
||||
|
||||
driver.run( args, 'jambu', CONF, 'rv32', 'nist', NIST_IMP = 'ref' )
|
||||
driver.run( args, 'jambu', CONF, 'rv32', 'nist', NIST_IMP = 'opt' )
|
||||
|
||||
for TYPE in [ 'JAMBU_RV32_TYPE1', 'JAMBU_RV32_TYPE2', 'JAMBU_RV32_TYPE3' ] :
|
||||
CONF = [ TYPE ]
|
||||
# there is only unrolled implementation for TinyJAMBU on rv32
|
||||
CONF += [ 'JAMBU_RV32_UNROLL' ]
|
||||
|
||||
driver.run( args, 'jambu', CONF, 'rv32', 'rv32', NIST_IMP = 'opt' )
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
def rv64( args ) :
|
||||
if ( args.nist ) :
|
||||
CONF = []
|
||||
|
||||
driver.run( args, 'jambu', CONF, 'rv64', 'nist', NIST_IMP = 'ref' )
|
||||
driver.run( args, 'jambu', CONF, 'rv64', 'nist', NIST_IMP = 'opt' )
|
||||
|
||||
for TYPE in [ 'JAMBU_RV64_TYPE1', 'JAMBU_RV64_TYPE2' ] :
|
||||
for UNROLL in [ False, True ] :
|
||||
CONF = [ TYPE ]
|
||||
|
||||
if ( UNROLL ) :
|
||||
CONF += [ 'JAMBU_RV64_UNROLL' ]
|
||||
|
||||
driver.run( args, 'jambu', CONF, 'rv64', 'rv64' )
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
if ( __name__ == '__main__' ) :
|
||||
driver.main( rv32, rv64 )
|
||||
|
||||
# =============================================================================
|
Reference in New Issue
Block a user