adds initial version of lwc

This commit is contained in:
2025-01-16 16:38:16 +01:00
parent 74c2ec2014
commit 2d8b8dc34a
2528 changed files with 578574 additions and 0 deletions

29
lwc/src/jambu/Makefile.in Normal file
View 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
# =============================================================================

View 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
// ============================================================================

View 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
// ============================================================================

View 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 )
# =============================================================================

View 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
View 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
View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:289ef4421dbf0008cc36a8cb1ea7b84b7a5e6fbd862f0d49ded3407379cf6c43
size 871275

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a5f3b677be97696b9575016de40261b0ca11039dd45d79ec891fc35b68b49d96
size 1307095

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:29ab0c72e87a9bbaa1a1bee969c462aa6a7dcb0a5cc9b51ae2499f56c5bff676
size 143105

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:9c9c33eceff69413f0734bec72c2dc857f001ac316ffc4fb9b74f111a8451a76
size 45506

View File

@@ -0,0 +1,5 @@
#define CRYPTO_KEYBYTES 16
#define CRYPTO_NSECBYTES 0
#define CRYPTO_NPUBBYTES 12
#define CRYPTO_ABYTES 8
#define CRYPTO_NOOVERLAP 1

View File

@@ -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;
}

View File

@@ -0,0 +1,5 @@
#define CRYPTO_KEYBYTES 16
#define CRYPTO_NSECBYTES 0
#define CRYPTO_NPUBBYTES 12
#define CRYPTO_ABYTES 8
#define CRYPTO_NOOVERLAP 1

View File

@@ -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;
}

View File

@@ -0,0 +1,5 @@
#define CRYPTO_KEYBYTES 24
#define CRYPTO_NSECBYTES 0
#define CRYPTO_NPUBBYTES 12
#define CRYPTO_ABYTES 8
#define CRYPTO_NOOVERLAP 1

View File

@@ -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;
}

View File

@@ -0,0 +1,5 @@
#define CRYPTO_KEYBYTES 24
#define CRYPTO_NSECBYTES 0
#define CRYPTO_NPUBBYTES 12
#define CRYPTO_ABYTES 8
#define CRYPTO_NOOVERLAP 1

View File

@@ -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;
}

View File

@@ -0,0 +1,5 @@
#define CRYPTO_KEYBYTES 32
#define CRYPTO_NSECBYTES 0
#define CRYPTO_NPUBBYTES 12
#define CRYPTO_ABYTES 8
#define CRYPTO_NOOVERLAP 1

View File

@@ -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;
}

View File

@@ -0,0 +1,5 @@
#define CRYPTO_KEYBYTES 32
#define CRYPTO_NSECBYTES 0
#define CRYPTO_NPUBBYTES 12
#define CRYPTO_ABYTES 8
#define CRYPTO_NOOVERLAP 1

View File

@@ -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
View 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 )
# =============================================================================