975 lines
30 KiB
C
975 lines
30 KiB
C
#include <ph_HWVariants.h>
|
|
#include <ph_TypeDefs.h>
|
|
#include <phCl_TypeDefs.h>
|
|
#include <phIlibMem.h>
|
|
#include <phIlibMemRAM.h>
|
|
#include <phIlibSfrUmPkcc.h>
|
|
#include <phIlibSfrUmRng.h>
|
|
#include <phClUtilsAsym_FameWordSize.h>
|
|
#include "SecureboxMemConfig.h"
|
|
|
|
|
|
/* This code supports:
|
|
*
|
|
* secp256k1 for ECDSA
|
|
* BLS12-381 G2 for BLS signatures
|
|
*
|
|
* The implementation of ECDSA relies on receiving precomputed k and k x G.
|
|
* The reason for this is that we want to use the card's native ECC Fp point multiplication,
|
|
* which is not exposed through the C API but is exposed through the Javacard API.
|
|
*
|
|
*/
|
|
|
|
/*===========================================================================*
|
|
* Defines:
|
|
*===========================================================================*/
|
|
#define SB_BLS 1
|
|
#define SB_ECDSA 2
|
|
|
|
#define ECDSA_OP_SIZE 32
|
|
#define ECDSA_OP_WSIZE (ECDSA_OP_SIZE/2)
|
|
#define FP2_OP_SIZE 48
|
|
#define FP2_OP_WSIZE (FP2_OP_SIZE/2)
|
|
#define FP2_INT_WSIZE (FP2_OP_WSIZE * 2)
|
|
#define BLS_POINT_WSIZE (FP2_INT_WSIZE * 3)
|
|
#define FAME_OW_SIZE (PH_CLUTILS_FAME_WORD_SIZE/2)
|
|
|
|
#define FAME_WAIT(mask) do { dcw_dci(); } while(gphlibSfrUm_PKCC_STATUS.bVal & mask);
|
|
#define FAME_PTR(addr) (((uint16_t) addr) - SB_INFO_STRUCT_START)
|
|
#define FAME_RPTR(addr) ((uint16_t*)(addr + SB_INFO_STRUCT_START))
|
|
#define FAME_WALLOC(mem, size) &mem[size]; mem += size
|
|
|
|
#define FUP_ENTRY(p0, p1, x, y, z, r) (p0|(p1 << 8)), (x|(y << 8)), (z|(r << 8))
|
|
#define FMC_ENTRY(a, b) (a|(b << 8))
|
|
#define FAME_USER_MACRO_ADDR 0x80
|
|
#define FAME_USER_MACRO_WLEN 27
|
|
#define FAME_MC_MODINVO FAME_USER_MACRO_ADDR
|
|
#define FAME_MC_MODINVE (FAME_MC_MODINVO + 26)
|
|
#define FAME_MC_FIXS (FAME_MC_MODINVE + 21)
|
|
|
|
#define ECDSA_SIGN_LEN 6
|
|
#define FP2_SUB_LEN 2
|
|
#define FP2_ADD_LEN 2
|
|
#define FP2_MULT_FP2_LEN 8
|
|
#define FP2_SQUARE_LEN 5
|
|
#define FP2_MULT_FP_LEN 2
|
|
#define FP2_PRE_INV_LEN 3
|
|
#define FP2_POST_INV_LEN 3
|
|
#define BLS_MONTGOMERY_TOGGLEXY_LEN 4
|
|
|
|
#define FM_NEG 0x09
|
|
#define FM_ADD 0x0a
|
|
#define FM_SUB 0x0b
|
|
#define FM_OR 0x0e
|
|
#define FM_SHR 0x15
|
|
#define FM_ANDC 0x1d
|
|
#define FM_LSB 0x2d
|
|
#define FM_CNST 0x3e
|
|
#define FM_CMP 0x4b
|
|
|
|
#define FMC_MONPRO 0x00
|
|
#define FMC_MODADD 0x21
|
|
#define FMC_MODSUB 0x2a
|
|
|
|
#define FUP_MACRO 0x80
|
|
#define FUP_PRIMITIVE 0x00
|
|
|
|
#define FMC_PTR 0x00
|
|
#define FMC_CONST 0x01
|
|
#define FMC_T 0x10
|
|
#define FMC_Z 0x00
|
|
|
|
#define FMC_TXP 0x80
|
|
#define FMC_T2P 0x40
|
|
#define FMC_P2T 0x00
|
|
|
|
#define FMC_PADD 0x28
|
|
#define FMC_PSUB 0x20
|
|
#define FMC_PINC 0x18
|
|
#define FMC_PDEC 0x10
|
|
|
|
#define FMC_PX 0x00
|
|
#define FMC_PY 0x01
|
|
#define FMC_PZ 0x02
|
|
#define FMC_PR 0x03
|
|
#define FMC_PS 0x04
|
|
#define FMC_PT 0x05
|
|
#define FMC_PL 0x06
|
|
#define FMC_PC 0x07
|
|
|
|
#define FMC_Z0C0 0x00
|
|
#define FMC_Z0C1 0x01
|
|
#define FMC_Z1C0 0x02
|
|
#define FMC_Z1C1 0x03
|
|
#define FMC_Z0 0x04
|
|
#define FMC_Z1 0x05
|
|
#define FMC_C0 0x06
|
|
#define FMC_C1 0x07
|
|
|
|
#define FMC_XYZR 0x00
|
|
#define FMC_ZRZR 0x01
|
|
#define FMC_XYRR 0x02
|
|
#define FMC_XYXY 0x03
|
|
#define FMC_XXYX 0x04
|
|
#define FMC_XZRR 0x05
|
|
#define FMC_XRXR 0x06
|
|
#define FMC_XXYR 0x07
|
|
#define FMC_XZRZ 0x08
|
|
#define FMC_XYRY 0x09
|
|
#define FMC_YRZZ 0x0a
|
|
|
|
#define FMC_EXC(ins) (0x80|ins)
|
|
#define FMC_DTBNZ(adr) (0x40|addr)
|
|
#define FMC_CNFLD(csrc, conf) (0x20|csrc|conf)
|
|
#define FMC_INDEC(indec, ptr) (0x10|indec|ptr)
|
|
#define FMC_CJMP(cond) (0x08|cond)
|
|
#define FMC_PRLD(conf) (0x02|conf)
|
|
#define FMC_JMP 0x01
|
|
#define FMC_EXT 0x00
|
|
|
|
/*===========================================================================*
|
|
* Structures:
|
|
*===========================================================================*/
|
|
typedef struct LLVM_UNALIGNED {
|
|
uint16_t FAME_MEMORY_TYPE im[FP2_OP_WSIZE];
|
|
uint16_t FAME_MEMORY_TYPE re[FP2_OP_WSIZE];
|
|
} fp2_int_t;
|
|
|
|
typedef struct LLVM_UNALIGNED {
|
|
fp2_int_t x;
|
|
fp2_int_t y;
|
|
fp2_int_t z;
|
|
} bls_point_t;
|
|
|
|
/*===========================================================================*
|
|
* Globals:
|
|
*===========================================================================*/
|
|
uint16_t* FAME_MEMORY_TYPE fameMem = (uint16_t* FAME_MEMORY_TYPE) SB_WORKSPACE_START;
|
|
DM32_MEMORY_TYPE uint16_t* fup = NULL;
|
|
|
|
const uint16_t SECP256K1_R2_NDASH_N[] = {
|
|
// R^2
|
|
0xd140, 0x67d7, 0xf214, 0x896c,
|
|
0xf878, 0x0e7c, 0x96c2, 0x7414,
|
|
0x07c6, 0x5bcd, 0xf5e4, 0xe697,
|
|
0x9bc5, 0x81c6, 0x1cd5, 0x9d67,
|
|
// NDASH
|
|
0xB13F, 0x5588, 0xFF66, 0x4B0D,
|
|
0xEC24, 0x34B9, 0x1AC8, 0x50A5,
|
|
// N (order of G)
|
|
0x4141, 0xD036, 0x5E8C, 0xBFD2,
|
|
0xA03B, 0xAF48, 0xDCE6, 0xBAAE,
|
|
0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF,
|
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
|
};
|
|
|
|
const uint16_t ECDSA_MAX_S[] = {
|
|
0x20A0, 0x681B, 0x2F46, 0xDFE9,
|
|
0x501D, 0x57A4, 0x6E73, 0x5D57,
|
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
|
0xFFFF, 0xFFFF, 0xFFFF, 0x7FFF
|
|
};
|
|
|
|
const uint16_t ECDSA_SIGN[] = {
|
|
FUP_ENTRY(FUP_MACRO, FMC_MONPRO, 0x01, 0x07, 0x05, 0x06),
|
|
FUP_ENTRY(FUP_MACRO, FMC_MONPRO, 0x06, 0x02, 0x05, 0x04),
|
|
FUP_ENTRY(FUP_MACRO, FMC_MODADD, 0x05, 0x00, 0x04, 0x06),
|
|
FUP_ENTRY(FUP_MACRO, FMC_MONPRO, 0x06, 0x07, 0x05, 0x04),
|
|
FUP_ENTRY(FUP_MACRO, FMC_MONPRO, 0x04, 0x03, 0x05, 0x06),
|
|
FUP_ENTRY(FUP_MACRO, FAME_MC_FIXS, 0x05, 0x06, 0x08, 0x06),
|
|
};
|
|
|
|
const uint16_t BLS12381_ONE[] = {
|
|
0xfffd, 0x0002, 0x0000, 0x7609,
|
|
0x0002, 0xc40c, 0x000b, 0xebf4,
|
|
0x58ba, 0x53c7, 0x9857, 0x5f48,
|
|
0x5745, 0x7052, 0x5853, 0x77ce,
|
|
0xec6d, 0xa256, 0x1a97, 0x5c07,
|
|
0xe493, 0xfa80, 0x5ec3, 0x15f6,
|
|
};
|
|
|
|
const uint16_t BLS12381_THREE[] = {
|
|
0xaaa1, 0x0009, 0x0000, 0xee1d,
|
|
0x0007, 0xe97c, 0x0025, 0x8684,
|
|
0x1de8, 0x0df4, 0x23c4, 0x4f78,
|
|
0xe051, 0x69ec, 0x71f0, 0x9e7c,
|
|
0x6b99, 0x606d, 0x005a, 0x7dde,
|
|
0xe085, 0x7c82, 0xf877, 0x0de0,
|
|
};
|
|
|
|
const uint16_t BLS12381_FOUR[] = {
|
|
0xfff3, 0x000c, 0x0000, 0xaa27,
|
|
0x000a, 0xfc34, 0x0032, 0x53cc,
|
|
0x807f, 0x6b0a, 0xe97a, 0x478f,
|
|
0x24d7, 0xe6ba, 0x7ebe, 0xb1d3,
|
|
0xab2f, 0xbf78, 0x733b, 0x8ec9,
|
|
0xde7e, 0x3d83, 0x4551, 0x09d6,
|
|
};
|
|
|
|
const uint16_t BLS12381_EIGHT[] = {
|
|
0xffe6, 0x0019, 0x0000, 0x544e,
|
|
0x0015, 0xf868, 0x0065, 0xa798,
|
|
0x00fe, 0xd615, 0xd2f4, 0x8f1f,
|
|
0x49ae, 0xcd74, 0xfd7d, 0x63a6,
|
|
0x565f, 0x7ef1, 0xe677, 0x1d92,
|
|
0xbcfd, 0x7b07, 0x8aa2, 0x13ac,
|
|
};
|
|
|
|
const uint16_t BLS12381_R2[] = {
|
|
0x1746, 0x1c34, 0x1f34, 0xf4df,
|
|
0x04f1, 0x09d1, 0xe6a6, 0x0a76,
|
|
0xb6d5, 0x4c95, 0x476c, 0x8de5,
|
|
0x83c0, 0x939d, 0x88a9, 0x67eb,
|
|
0x952d, 0xb519, 0x3e85, 0x9a79,
|
|
0xe3aa, 0x92ca, 0x8fe5, 0x1198,
|
|
};
|
|
|
|
const uint16_t BLS12381_NDASH_N[] = {
|
|
// NDASH
|
|
0xfffd, 0xfffc, 0xfffc, 0x89f3,
|
|
0x13e8, 0xd9d1, 0xdb92, 0x286a,
|
|
// N
|
|
0xaaab, 0xffff, 0xffff, 0xb9fe,
|
|
0xffff, 0xb153, 0xfffe, 0x1eab,
|
|
0xf624, 0xf6b0, 0xd2a0, 0x6730,
|
|
0x12bf, 0xf385, 0x4b84, 0x6477,
|
|
0xacd7, 0x434b, 0xa7b6, 0x4b1b,
|
|
0xe69a, 0x397f, 0x11ea, 0x1a01,
|
|
};
|
|
|
|
const uint16_t FP2_SUB[] = {
|
|
FUP_ENTRY(FUP_MACRO, FMC_MODSUB, 0x05, 0x00, 0x02, 0x06),
|
|
FUP_ENTRY(FUP_MACRO, FMC_MODSUB, 0x05, 0x01, 0x03, 0x07),
|
|
};
|
|
|
|
const uint16_t FP2_ADD[] = {
|
|
FUP_ENTRY(FUP_MACRO, FMC_MODADD, 0x05, 0x00, 0x02, 0x06),
|
|
FUP_ENTRY(FUP_MACRO, FMC_MODADD, 0x05, 0x01, 0x03, 0x07),
|
|
};
|
|
|
|
const uint16_t FP2_MULT_FP2[] = {
|
|
FUP_ENTRY(FUP_MACRO, FMC_MONPRO, 0x00, 0x02, 0x05, 0x06),
|
|
FUP_ENTRY(FUP_MACRO, FMC_MONPRO, 0x01, 0x03, 0x05, 0x07),
|
|
FUP_ENTRY(FUP_MACRO, FMC_MODADD, 0x05, 0x00, 0x01, 0x09),
|
|
FUP_ENTRY(FUP_MACRO, FMC_MODADD, 0x05, 0x02, 0x03, 0x0a),
|
|
FUP_ENTRY(FUP_MACRO, FMC_MODADD, 0x05, 0x06, 0x07, 0x0b),
|
|
FUP_ENTRY(FUP_MACRO, FMC_MODSUB, 0x05, 0x06, 0x07, 0x06),
|
|
FUP_ENTRY(FUP_MACRO, FMC_MONPRO, 0x09, 0x0a, 0x05, 0x07),
|
|
FUP_ENTRY(FUP_MACRO, FMC_MODSUB, 0x05, 0x07, 0x0b, 0x07),
|
|
};
|
|
|
|
const uint16_t FP2_SQUARE[] = {
|
|
FUP_ENTRY(FUP_MACRO, FMC_MODSUB, 0x05, 0x00, 0x01, 0x0a),
|
|
FUP_ENTRY(FUP_MACRO, FMC_MODADD, 0x05, 0x00, 0x01, 0x0b),
|
|
FUP_ENTRY(FUP_MACRO, FMC_MONPRO, 0x0a, 0x0b, 0x05, 0x06),
|
|
FUP_ENTRY(FUP_MACRO, FMC_MONPRO, 0x00, 0x01, 0x05, 0x07),
|
|
FUP_ENTRY(FUP_MACRO, FMC_MODADD, 0x05, 0x07, 0x07, 0x07),
|
|
};
|
|
|
|
const uint16_t FP2_MULT_FP[] = {
|
|
FUP_ENTRY(FUP_MACRO, FMC_MONPRO, 0x04, 0x00, 0x05, 0x06),
|
|
FUP_ENTRY(FUP_MACRO, FMC_MONPRO, 0x04, 0x01, 0x05, 0x07),
|
|
};
|
|
|
|
const uint16_t FP2_PRE_INV[] = {
|
|
FUP_ENTRY(FUP_MACRO, FMC_MONPRO, 0x00, 0x00, 0x05, 0x06),
|
|
FUP_ENTRY(FUP_MACRO, FMC_MONPRO, 0x01, 0x01, 0x05, 0x07),
|
|
FUP_ENTRY(FUP_MACRO, FMC_MODADD, 0x05, 0x06, 0x07, 0x02),
|
|
};
|
|
|
|
const uint16_t FP2_POST_INV[] = {
|
|
FUP_ENTRY(FUP_MACRO, FMC_MODSUB, 0x05, 0x0b, 0x01, 0x0a),
|
|
FUP_ENTRY(FUP_MACRO, FMC_MONPRO, 0x02, 0x00, 0x05, 0x06),
|
|
FUP_ENTRY(FUP_MACRO, FMC_MONPRO, 0x02, 0x0a, 0x05, 0x07),
|
|
};
|
|
|
|
const uint16_t BLS_MONTGOMERY_TOGGLEXY[] = {
|
|
FUP_ENTRY(FUP_MACRO, FMC_MONPRO, 0x00, 0x04, 0x05, 0x06),
|
|
FUP_ENTRY(FUP_MACRO, FMC_MONPRO, 0x01, 0x04, 0x05, 0x07),
|
|
FUP_ENTRY(FUP_MACRO, FMC_MONPRO, 0x02, 0x04, 0x05, 0x09),
|
|
FUP_ENTRY(FUP_MACRO, FMC_MONPRO, 0x03, 0x04, 0x05, 0x0a),
|
|
};
|
|
|
|
const uint16_t FAME_USER_MACRO[] = {
|
|
// ODD
|
|
FMC_ENTRY(FMC_CNFLD(FMC_T, FMC_XZRZ), FMC_EXC(FM_SUB)),
|
|
FMC_ENTRY(FMC_PRLD(FMC_PTR), (FMC_P2T|FMC_PC)),
|
|
FMC_ENTRY(FMC_CNFLD(FMC_T, FMC_XYXY), FMC_EXC(FM_CMP)),
|
|
FMC_ENTRY(FMC_CJMP(FMC_C0), 0x05),
|
|
FMC_ENTRY(FMC_PRLD(FMC_PTR), (FMC_T2P|FMC_PR)),
|
|
FMC_ENTRY(FMC_CNFLD(FMC_T, FMC_XYRY), FMC_EXC(FM_ADD)),
|
|
FMC_ENTRY(FMC_CNFLD(FMC_T, FMC_XYXY), FMC_EXC(FM_SUB)),
|
|
FMC_ENTRY(FMC_PRLD(FMC_PTR), (FMC_T2P|FMC_PX)),
|
|
FMC_ENTRY(FMC_PRLD(FMC_PTR), (FMC_TXP|FMC_PY)),
|
|
FMC_ENTRY(FMC_PRLD(FMC_PTR), (FMC_T2P|FMC_PR)),
|
|
FMC_ENTRY(FMC_PRLD(FMC_PTR), (FMC_P2T|FMC_PL)),
|
|
FMC_ENTRY(FMC_PRLD(FMC_PTR), (FMC_P2T|FMC_PSUB|FMC_PX)),
|
|
FMC_ENTRY(FMC_PRLD(FMC_PTR), (FMC_T2P|FMC_PX)),
|
|
// EVEN
|
|
FMC_ENTRY(FMC_PRLD(FMC_CONST), 0x01),
|
|
FMC_ENTRY(FMC_CNFLD(FMC_T, FMC_XZRZ), FMC_EXC(FM_SHR)),
|
|
FMC_ENTRY(FMC_EXC(FM_LSB), FMC_CJMP(FMC_Z0)),
|
|
FMC_ENTRY(0x05, FMC_CNFLD(FMC_T, FMC_XYRR)),
|
|
FMC_ENTRY(FMC_EXC(FM_ADD), FMC_CJMP(FMC_C1)),
|
|
FMC_ENTRY(0x05, FMC_CNFLD(FMC_T, FMC_XXYX)),
|
|
FMC_ENTRY(FMC_PRLD(FMC_CONST), 0x00),
|
|
FMC_ENTRY(FMC_EXC(FM_CNST), FMC_CNFLD(FMC_T, FMC_XRXR)),
|
|
FMC_ENTRY(FMC_PRLD(FMC_CONST), 0x01),
|
|
FMC_ENTRY(FMC_EXC(FM_SHR), FMC_EXC(FM_OR)),
|
|
// FIX S
|
|
FMC_ENTRY(FMC_EXT, FMC_EXC(FM_CMP)),
|
|
FMC_ENTRY(FMC_CJMP(FMC_C1), 0x3),
|
|
FMC_ENTRY(FMC_CNFLD(FMC_T, FMC_XXYR), FMC_EXC(FM_SUB)),
|
|
FMC_ENTRY(FMC_EXT, 0xff),
|
|
};
|
|
|
|
void fame_open() {
|
|
gphlibSfrUm_PKCC_CTRL.bVal &= (uint8_t) ~PHLIB_SFRUMPKCC_CTRL_STOP_MASK;
|
|
while(gphlibSfrUm_PKCC_CTRL.bVal & PHLIB_SFRUMPKCC_CTRL_STOP_MASK);
|
|
|
|
gphlibSfrUm_PKCC_CTRL.bVal &= (uint8_t)~PHLIB_SFRUMPKCC_CTRL_RESET_MASK;
|
|
while(gphlibSfrUm_PKCC_CTRL.bVal & PHLIB_SFRUMPKCC_CTRL_RESET_MASK);
|
|
}
|
|
|
|
void fame_close() {
|
|
gphlibSfrUm_PKCC_CTRL.bVal |= PHLIB_SFRUMPKCC_CTRL_RESET_MASK;
|
|
while((gphlibSfrUm_PKCC_CTRL.bVal & PHLIB_SFRUMPKCC_CTRL_RESET_MASK) != PHLIB_SFRUMPKCC_CTRL_RESET_MASK);
|
|
|
|
gphlibSfrUm_PKCC_CTRL.bVal |= PHLIB_SFRUMPKCC_CTRL_STOP_MASK;
|
|
while((gphlibSfrUm_PKCC_CTRL.bVal & PHLIB_SFRUMPKCC_CTRL_STOP_MASK) != PHLIB_SFRUMPKCC_CTRL_STOP_MASK);
|
|
}
|
|
|
|
uint8_t fame_cmp(uint16_t* FAME_MEMORY_TYPE a, uint16_t* FAME_MEMORY_TYPE b) {
|
|
FAME_WAIT(PHLIB_SFRUMPKCC_STATUS_GOANY_MASK);
|
|
|
|
gphlibSfrUm_PKCC_YPTR.wVal = FAME_PTR(a);
|
|
gphlibSfrUm_PKCC_TOPP.wVal = FAME_PTR(b);
|
|
gphlibSfrUm_PKCC_MODE.bVal = FM_CMP;
|
|
|
|
gphlibSfrUm_PKCC_START.bVal = PHLIB_SFRUMPKCC_START_GOD1_MASK;
|
|
FAME_WAIT(PHLIB_SFRUMPKCC_STATUS_ACTV_MASK);
|
|
|
|
return gphlibSfrUm_PKCC_STATUS.bVal & 0x3;
|
|
}
|
|
|
|
void fame_rshift(uint16_t* FAME_MEMORY_TYPE a, uint16_t n) {
|
|
FAME_WAIT(PHLIB_SFRUMPKCC_STATUS_GOANY_MASK);
|
|
|
|
gphlibSfrUm_PKCC_YPTR.wVal = FAME_PTR(a);
|
|
gphlibSfrUm_PKCC_TOPP.wVal = n;
|
|
gphlibSfrUm_PKCC_RPTR.wVal = FAME_PTR(a);
|
|
gphlibSfrUm_PKCC_MODE.bVal = FM_SHR;
|
|
|
|
gphlibSfrUm_PKCC_START.bVal = PHLIB_SFRUMPKCC_START_GOD1_MASK;
|
|
FAME_WAIT(PHLIB_SFRUMPKCC_STATUS_ACTV_MASK);
|
|
}
|
|
|
|
void fame_modInvEven(uint16_t* ab, uint16_t* uv, uint16_t* FAME_MEMORY_TYPE n) {
|
|
FAME_WAIT(PHLIB_SFRUMPKCC_STATUS_GOANY_MASK);
|
|
|
|
n[-1] = 0x8000;
|
|
gphlibSfrUm_PKCC_XPTR.wVal = FAME_PTR(n) - gphlibSfrUm_PKCC_OPLEN.wVal;
|
|
gphlibSfrUm_PKCC_YPTR.wVal = FAME_PTR(n);
|
|
gphlibSfrUm_PKCC_TOPP.wVal = FAME_PTR(ab);
|
|
gphlibSfrUm_PKCC_RPTR.wVal = FAME_PTR(uv);
|
|
gphlibSfrUm_PKCC_MODE.bVal = FAME_MC_MODINVE;
|
|
|
|
gphlibSfrUm_PKCC_START.bVal = PHLIB_SFRUMPKCC_START_GOM1_MASK;
|
|
FAME_WAIT(PHLIB_SFRUMPKCC_STATUS_ACTV_MASK);
|
|
}
|
|
|
|
void fame_modInvOdd(uint16_t* FAME_MEMORY_TYPE ab, uint16_t* FAME_MEMORY_TYPE ba, uint16_t* FAME_MEMORY_TYPE uv, uint16_t* FAME_MEMORY_TYPE vu, uint16_t* FAME_MEMORY_TYPE n) {
|
|
FAME_WAIT(PHLIB_SFRUMPKCC_STATUS_GOANY_MASK);
|
|
|
|
n[-1] = 0x8000;
|
|
gphlibSfrUm_PKCC_XPTR.wVal = FAME_PTR(vu);
|
|
gphlibSfrUm_PKCC_YPTR.wVal = FAME_PTR(uv);
|
|
gphlibSfrUm_PKCC_TOPP.wVal = FAME_PTR(ab);
|
|
gphlibSfrUm_PKCC_RPTR.wVal = FAME_PTR(ba);
|
|
gphlibSfrUm_PKCC_MCLEN.wVal = FAME_PTR(n);
|
|
gphlibSfrUm_PKCC_MODE.bVal = FAME_MC_MODINVO;
|
|
|
|
gphlibSfrUm_PKCC_START.bVal = PHLIB_SFRUMPKCC_START_GOM1_MASK;
|
|
FAME_WAIT(PHLIB_SFRUMPKCC_STATUS_ACTV_MASK);
|
|
}
|
|
|
|
void fame_modInv(uint16_t* FAME_MEMORY_TYPE a, uint16_t* FAME_MEMORY_TYPE b, uint16_t* FAME_MEMORY_TYPE u, uint16_t* FAME_MEMORY_TYPE v, uint16_t* FAME_MEMORY_TYPE n) {
|
|
uint8_t cmp;
|
|
|
|
while((cmp = fame_cmp(a, b)) != 2) {
|
|
if (!(a[0] & 0x1)) {
|
|
fame_modInvEven(a, u, n);
|
|
} else if (!(b[0] & 0x1)) {
|
|
fame_modInvEven(b, v, n);
|
|
} else if (!(cmp & 0x1)) {
|
|
fame_modInvOdd(a, b, u, v, n);
|
|
} else {
|
|
fame_modInvOdd(b, a, v, u, n);
|
|
}
|
|
}
|
|
}
|
|
|
|
void rng(uint8_t* t, uint16_t len) {
|
|
if (gphlibSfrUm_RNG_CTRL.bVal & PHLIB_SFRUMRNG_CTRL_SQC_ERROR) {
|
|
gphlibSfrUm_RNG_CTRL.bVal |= PHLIB_SFRUMRNG_CTRL_SEEDREQ_MASK;
|
|
gphlibSfrUm_RNG_CTRL.bVal &= (uint8_t) ~(PHLIB_SFRUMRNG_CTRL_SEEDREQ_MASK | PHLIB_SFRUMRNG_CTRL_SQC_ERROR);
|
|
}
|
|
|
|
while(!(gphlibSfrUm_RNG_CTRL.bVal & PHLIB_SFRUMRNG_CTRL_RDY_HWRNG_MASK));
|
|
|
|
while(len--) {
|
|
t[len] = gphlibSfrUm_RNG_RND.bVal;
|
|
}
|
|
}
|
|
|
|
void fame_monpro(uint16_t* FAME_MEMORY_TYPE a, uint16_t* FAME_MEMORY_TYPE b, uint16_t* FAME_MEMORY_TYPE n, uint16_t* FAME_MEMORY_TYPE r) {
|
|
FAME_WAIT(PHLIB_SFRUMPKCC_STATUS_GOANY_MASK);
|
|
|
|
gphlibSfrUm_PKCC_XPTR.wVal = FAME_PTR(a);
|
|
gphlibSfrUm_PKCC_YPTR.wVal = FAME_PTR(b);
|
|
gphlibSfrUm_PKCC_TOPP.wVal = FAME_PTR(n);
|
|
gphlibSfrUm_PKCC_RPTR.wVal = FAME_PTR(r);
|
|
gphlibSfrUm_PKCC_MCLEN.wVal = ECDSA_OP_SIZE;
|
|
gphlibSfrUm_PKCC_MODE.bVal = FMC_MONPRO;
|
|
|
|
gphlibSfrUm_PKCC_START.bVal = PHLIB_SFRUMPKCC_START_GOM1_MASK;
|
|
FAME_WAIT(PHLIB_SFRUMPKCC_STATUS_ACTV_MASK);
|
|
}
|
|
|
|
static inline void fame_blind(uint16_t* FAME_MEMORY_TYPE a, uint16_t* FAME_MEMORY_TYPE n, uint16_t* FAME_MEMORY_TYPE t, uint16_t* FAME_MEMORY_TYPE r) {
|
|
rng((uint8_t*)t, ECDSA_OP_SIZE);
|
|
fame_monpro(a, t, n, r);
|
|
}
|
|
|
|
static inline void fame_unblind(uint16_t* FAME_MEMORY_TYPE a, uint16_t* FAME_MEMORY_TYPE n, uint16_t* FAME_MEMORY_TYPE t, uint16_t* FAME_MEMORY_TYPE r) {
|
|
fame_monpro(a, t, n, r);
|
|
}
|
|
|
|
void fame_ecdsaSign(uint16_t* FAME_MEMORY_TYPE uptable) {
|
|
FAME_WAIT(PHLIB_SFRUMPKCC_STATUS_GOANY_MASK);
|
|
|
|
gphlibSfrUm_PKCC_MCLEN.wVal = ECDSA_OP_SIZE;
|
|
gphlibSfrUm_PKCC_UPCTRL.bVal = PHLIB_SFRUMPKCC_UPCTRL_CACHE_EN_MASK;
|
|
gphlibSfrUm_PKCC_UPLEN.bVal = ECDSA_SIGN_LEN;
|
|
gphlibSfrUm_PKCC_UPTRT.wVal = FAME_PTR(uptable);
|
|
|
|
fup = ECDSA_SIGN;
|
|
|
|
gphlibSfrUm_PKCC_START.bVal = PHLIB_SFRUMPKCC_START_GOU_MASK;
|
|
|
|
gphlibSfrUm_PKCC_UPIRQ.bVal |= PHLIB_SFRUMPKCC_UPIRQ_LVL_MASK_VALUE_HIGH;
|
|
|
|
FAME_WAIT(PHLIB_SFRUMPKCC_STATUS_ACTV_MASK);
|
|
}
|
|
|
|
void flipmpi(uint8_t* mpi, uint16_t size) {
|
|
uint8_t *end = mpi + (size - 1);
|
|
|
|
while(end > mpi) {
|
|
uint8_t s = *mpi;
|
|
*(mpi++) = *end;
|
|
*(end--) = s;
|
|
}
|
|
|
|
}
|
|
|
|
void fame_fp2_do(uint16_t* FAME_MEMORY_TYPE uptable, fp2_int_t* a, fp2_int_t* b, fp2_int_t* r, const uint16_t* op, uint16_t oplen) {
|
|
FAME_WAIT(PHLIB_SFRUMPKCC_STATUS_GOANY_MASK);
|
|
|
|
uptable[0] = FAME_PTR(a->re);
|
|
uptable[1] = FAME_PTR(a->im);
|
|
uptable[2] = FAME_PTR(b->re);
|
|
uptable[3] = FAME_PTR(b->im);
|
|
|
|
gphlibSfrUm_PKCC_UPLEN.bVal = oplen;
|
|
fup = op;
|
|
|
|
gphlibSfrUm_PKCC_START.bVal = PHLIB_SFRUMPKCC_START_GOU_MASK;
|
|
gphlibSfrUm_PKCC_UPIRQ.bVal |= PHLIB_SFRUMPKCC_UPIRQ_LVL_MASK_VALUE_HIGH;
|
|
|
|
FAME_WAIT(PHLIB_SFRUMPKCC_STATUS_ACTV_MASK);
|
|
|
|
uint16_t* rre = FAME_RPTR(uptable[6]);
|
|
uint16_t* rim = FAME_RPTR(uptable[7]);
|
|
|
|
for (uint8_t i = 0; i < FP2_OP_WSIZE; i++) {
|
|
r->re[i] = rre[i];
|
|
r->im[i] = rim[i];
|
|
}
|
|
}
|
|
|
|
static inline void fame_fp2_sub(uint16_t* FAME_MEMORY_TYPE uptable, fp2_int_t* a, fp2_int_t* b, fp2_int_t* r) {
|
|
fame_fp2_do(uptable, a, b, r, FP2_SUB, FP2_SUB_LEN);
|
|
}
|
|
|
|
static inline void fame_fp2_add(uint16_t* FAME_MEMORY_TYPE uptable, fp2_int_t* a, fp2_int_t* b, fp2_int_t* r) {
|
|
fame_fp2_do(uptable, a, b, r, FP2_ADD, FP2_ADD_LEN);
|
|
}
|
|
|
|
static inline void fame_fp2_mult_fp2(uint16_t* FAME_MEMORY_TYPE uptable, fp2_int_t* a, fp2_int_t* b, fp2_int_t* r) {
|
|
fame_fp2_do(uptable, a, b, r, FP2_MULT_FP2, FP2_MULT_FP2_LEN);
|
|
}
|
|
|
|
static inline void fame_fp2_square(uint16_t* FAME_MEMORY_TYPE uptable, fp2_int_t* a, fp2_int_t* r) {
|
|
fame_fp2_do(uptable, a, a, r, FP2_SQUARE, FP2_SQUARE_LEN);
|
|
}
|
|
|
|
void fame_fp2_mult_fp(uint16_t* FAME_MEMORY_TYPE uptable, fp2_int_t* a, const uint16_t* num, fp2_int_t* r) {
|
|
uint16_t* r2 = FAME_RPTR(uptable[4]);
|
|
|
|
for (uint8_t i = 0; i < FP2_OP_WSIZE; i++) {
|
|
r2[i] = num[i];
|
|
}
|
|
|
|
fame_fp2_do(uptable, a, a, r, FP2_MULT_FP, FP2_MULT_FP_LEN);
|
|
}
|
|
|
|
void fame_fp2_invert(uint16_t* FAME_MEMORY_TYPE uptable, fp2_int_t* a, fp2_int_t* r) {
|
|
FAME_WAIT(PHLIB_SFRUMPKCC_STATUS_GOANY_MASK);
|
|
|
|
uptable[0] = FAME_PTR(a->re);
|
|
uptable[1] = FAME_PTR(a->im);
|
|
uptable[2] = uptable[9];
|
|
|
|
gphlibSfrUm_PKCC_UPLEN.bVal = FP2_PRE_INV_LEN;
|
|
fup = FP2_PRE_INV;
|
|
|
|
gphlibSfrUm_PKCC_START.bVal = PHLIB_SFRUMPKCC_START_GOU_MASK;
|
|
gphlibSfrUm_PKCC_UPIRQ.bVal |= PHLIB_SFRUMPKCC_UPIRQ_LVL_MASK_VALUE_HIGH;
|
|
|
|
FAME_WAIT(PHLIB_SFRUMPKCC_STATUS_ACTV_MASK);
|
|
|
|
uint16_t* factor = FAME_RPTR(uptable[9]);
|
|
uint16_t* b = FAME_RPTR(uptable[6]);
|
|
uint16_t* u = FAME_RPTR(uptable[7]);
|
|
uint16_t* v = FAME_RPTR(uptable[4]);
|
|
uint16_t* t1 = FAME_RPTR(uptable[10]);
|
|
uint16_t* n = FAME_RPTR(uptable[11]);
|
|
|
|
for (uint8_t i = 0; i < FP2_OP_WSIZE; i++) {
|
|
b[i] = n[i] = BLS12381_NDASH_N[i+FAME_OW_SIZE];
|
|
t1[i] = v[i] = 0x0000;
|
|
u[i] = BLS12381_R2[i];
|
|
}
|
|
|
|
fame_modInv(factor, b, u, v, n);
|
|
|
|
for (uint8_t i = 0; i < FP2_OP_WSIZE; i++) {
|
|
factor[i] = u[i];
|
|
n[i] = 0x0000;
|
|
}
|
|
|
|
gphlibSfrUm_PKCC_MCLEN.wVal = FP2_OP_SIZE;
|
|
gphlibSfrUm_PKCC_UPLEN.bVal = FP2_POST_INV_LEN;
|
|
fup = FP2_POST_INV;
|
|
|
|
gphlibSfrUm_PKCC_START.bVal = PHLIB_SFRUMPKCC_START_GOU_MASK;
|
|
gphlibSfrUm_PKCC_UPIRQ.bVal |= PHLIB_SFRUMPKCC_UPIRQ_LVL_MASK_VALUE_HIGH;
|
|
|
|
FAME_WAIT(PHLIB_SFRUMPKCC_STATUS_ACTV_MASK);
|
|
|
|
for (uint8_t i = 0; i < FP2_OP_WSIZE; i++) {
|
|
r->re[i] = b[i];
|
|
r->im[i] = u[i];
|
|
}
|
|
}
|
|
|
|
void fame_load_macros() {
|
|
gphlibSfrUm_PKCC_MODE.bVal = FAME_USER_MACRO_ADDR;
|
|
|
|
for (uint8_t i = 0; i < FAME_USER_MACRO_WLEN; i++) {
|
|
gphlibSfrUm_PKCC_MCDATA.wVal = FAME_USER_MACRO[i];
|
|
}
|
|
}
|
|
|
|
uint8_t is_zero256(uint8_t* buf) {
|
|
uint8_t res = 0;
|
|
|
|
for (int i = 0; i < 32; i++) {
|
|
res |= buf[i];
|
|
}
|
|
|
|
return !res;
|
|
}
|
|
|
|
uint16_t ecdsaSign() {
|
|
uint16_t* FAME_MEMORY_TYPE d = fameMem;
|
|
uint16_t* FAME_MEMORY_TYPE x = &d[ECDSA_OP_WSIZE];
|
|
uint16_t* FAME_MEMORY_TYPE z = &x[ECDSA_OP_WSIZE];
|
|
uint16_t* FAME_MEMORY_TYPE k = &z[ECDSA_OP_WSIZE];
|
|
uint16_t* FAME_MEMORY_TYPE uptable = &k[ECDSA_OP_WSIZE];
|
|
uint16_t* FAME_MEMORY_TYPE b = &uptable[ECDSA_OP_WSIZE];
|
|
uint16_t* FAME_MEMORY_TYPE u = &b[ECDSA_OP_WSIZE];
|
|
uint16_t* FAME_MEMORY_TYPE v = &u[ECDSA_OP_WSIZE];
|
|
uint16_t* FAME_MEMORY_TYPE t1 = &v[ECDSA_OP_WSIZE];
|
|
uint16_t* FAME_MEMORY_TYPE y1 = &t1[ECDSA_OP_WSIZE];
|
|
uint16_t* FAME_MEMORY_TYPE t2 = &y1[ECDSA_OP_WSIZE];
|
|
uint16_t* FAME_MEMORY_TYPE t3 = &t2[ECDSA_OP_WSIZE+FAME_OW_SIZE];
|
|
|
|
flipmpi((uint8_t*)k, ECDSA_OP_SIZE);
|
|
flipmpi((uint8_t*)d, ECDSA_OP_SIZE);
|
|
flipmpi((uint8_t*)x, ECDSA_OP_SIZE);
|
|
flipmpi((uint8_t*)z, ECDSA_OP_SIZE);
|
|
|
|
for (uint8_t i = 0; i < ECDSA_OP_WSIZE; i++) {
|
|
uptable[i] = SECP256K1_R2_NDASH_N[i+FAME_OW_SIZE];
|
|
b[i] = SECP256K1_R2_NDASH_N[i+ECDSA_OP_WSIZE+FAME_OW_SIZE];
|
|
u[i] = 0x0000;
|
|
v[i] = 0x0000;
|
|
t1[i] = 0x0000;
|
|
y1[i] = b[i];
|
|
}
|
|
|
|
FAME_WAIT(PHLIB_SFRUMPKCC_STATUS_GOANY);
|
|
|
|
gphlibSfrUm_PKCC_OPLEN.wVal = ECDSA_OP_SIZE;
|
|
|
|
fame_load_macros();
|
|
|
|
fame_blind(k, b, t2, t3);
|
|
u[0] = 0x0001;
|
|
fame_modInv(t3, b, u, v, y1);
|
|
|
|
for (uint8_t i = 0; i < ECDSA_OP_WSIZE; i++) {
|
|
t1[i] = SECP256K1_R2_NDASH_N[i+FAME_OW_SIZE];
|
|
b[i] = SECP256K1_R2_NDASH_N[i];
|
|
k[i] = ECDSA_MAX_S[i];
|
|
}
|
|
|
|
fame_unblind(u, y1, t2, t3);
|
|
|
|
uptable[0] = FAME_PTR(z);
|
|
uptable[1] = FAME_PTR(d);
|
|
uptable[2] = FAME_PTR(x);
|
|
uptable[3] = FAME_PTR(t3);
|
|
uptable[4] = FAME_PTR(v);
|
|
uptable[5] = FAME_PTR(y1);
|
|
uptable[6] = FAME_PTR(t2);
|
|
uptable[7] = FAME_PTR(b);
|
|
uptable[8] = FAME_PTR(k);
|
|
|
|
fame_ecdsaSign(uptable);
|
|
|
|
uint8_t off = 0;
|
|
uint8_t* r = (uint8_t*)x;
|
|
uint8_t* s = (uint8_t*)t2;
|
|
uint8_t recIdInv = (gphlibSfrUm_PKCC_STATUS.bVal & 0x3) ? 0 : 1;
|
|
|
|
uint8_t* res = r;
|
|
|
|
if (is_zero256(s)) {
|
|
goto _ecdsa_finish;
|
|
}
|
|
|
|
flipmpi(r, ECDSA_OP_SIZE);
|
|
flipmpi(s, ECDSA_OP_SIZE);
|
|
|
|
off += 32;
|
|
|
|
for (uint8_t i = 0; i < ECDSA_OP_SIZE; i++) {
|
|
res[off++] = s[i];
|
|
}
|
|
|
|
res[off++] = recIdInv;
|
|
|
|
_ecdsa_finish:;
|
|
phNativeLibParameterArea_t* params = (phNativeLibParameterArea_t*)SB_INFO_STRUCT_START;
|
|
|
|
params->siCopyBackAddress = (puint8_uni_t) res;
|
|
params->siCopyBackSize = off;
|
|
params->scCopyBackAtomic = 0xff;
|
|
|
|
return off;
|
|
}
|
|
|
|
uint8_t bls_point_is_zero(bls_point_t* FAME_MEMORY_TYPE p) {
|
|
uint8_t res = 0;
|
|
|
|
for (uint16_t i = 0; i < FP2_OP_WSIZE; i++) {
|
|
res |= p->z.re[i];
|
|
res |= p->z.im[i];
|
|
}
|
|
|
|
return !res;
|
|
}
|
|
|
|
void bls_point_copy(bls_point_t* FAME_MEMORY_TYPE src, bls_point_t* FAME_MEMORY_TYPE dst) {
|
|
for (uint16_t i = 0; i < FP2_OP_WSIZE; i++) {
|
|
dst->x.re[i] = src->x.re[i];
|
|
dst->x.im[i] = src->x.im[i];
|
|
dst->y.re[i] = src->y.re[i];
|
|
dst->y.im[i] = src->y.im[i];
|
|
dst->z.re[i] = src->z.re[i];
|
|
dst->z.im[i] = src->z.im[i];
|
|
}
|
|
}
|
|
|
|
void bls_point_zero(bls_point_t* FAME_MEMORY_TYPE p) {
|
|
for (uint16_t i = 0; i < FP2_OP_WSIZE; i++) {
|
|
p->x.re[i] = BLS12381_ONE[i];
|
|
p->x.im[i] = 0x0000;
|
|
p->y.re[i] = BLS12381_ONE[i];
|
|
p->y.im[i] = 0x0000;
|
|
p->z.re[i] = 0x0000;
|
|
p->z.im[i] = 0x0000;
|
|
}
|
|
}
|
|
|
|
uint8_t fp2_int_equals(fp2_int_t* a, fp2_int_t* b) {
|
|
uint8_t res = 1;
|
|
|
|
for (uint16_t i = 0; i < FP2_OP_WSIZE; i++) {
|
|
res &= a->re[i] == b->re[i];
|
|
res &= a->im[i] == b->im[i];
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
void bls_point_double(uint16_t* FAME_MEMORY_TYPE uptable, uint16_t* FAME_MEMORY_TYPE scratch, bls_point_t* FAME_MEMORY_TYPE p) {
|
|
fp2_int_t* w = (fp2_int_t*) FAME_WALLOC(scratch, FP2_INT_WSIZE);
|
|
fp2_int_t* s = (fp2_int_t*) FAME_WALLOC(scratch, FP2_INT_WSIZE);
|
|
fp2_int_t* b = (fp2_int_t*) FAME_WALLOC(scratch, FP2_INT_WSIZE);
|
|
fp2_int_t* h = (fp2_int_t*) FAME_WALLOC(scratch, FP2_INT_WSIZE);
|
|
|
|
fame_fp2_mult_fp2(uptable, &p->y, &p->z, s);
|
|
|
|
fame_fp2_square(uptable, &p->x, &p->z);
|
|
fame_fp2_mult_fp(uptable, &p->z, BLS12381_THREE, w);
|
|
|
|
fame_fp2_mult_fp2(uptable, &p->x, &p->y, b);
|
|
fame_fp2_mult_fp2(uptable, b, s, b);
|
|
|
|
fame_fp2_mult_fp(uptable, b, BLS12381_EIGHT, &p->z);
|
|
fame_fp2_square(uptable, w, h);
|
|
|
|
fame_fp2_sub(uptable, h, &p->z, h);
|
|
|
|
fame_fp2_mult_fp2(uptable, h, s, &p->z);
|
|
fame_fp2_add(uptable, &p->z, &p->z, &p->x);
|
|
|
|
fame_fp2_mult_fp(uptable, b, BLS12381_FOUR, &p->z);
|
|
fame_fp2_sub(uptable, &p->z, h, b);
|
|
fame_fp2_square(uptable, &p->y, &p->z);
|
|
fame_fp2_mult_fp(uptable, &p->z, BLS12381_EIGHT, &p->y);
|
|
fame_fp2_square(uptable, s, &p->z);
|
|
fame_fp2_mult_fp2(uptable, &p->y, &p->z, &p->y);
|
|
fame_fp2_mult_fp2(uptable, w, b, w);
|
|
fame_fp2_sub(uptable, w, &p->y, &p->y);
|
|
|
|
fame_fp2_mult_fp2(uptable, s, &p->z, s);
|
|
fame_fp2_mult_fp(uptable, s, BLS12381_EIGHT, &p->z);
|
|
}
|
|
|
|
void bls_point_add(uint16_t* FAME_MEMORY_TYPE uptable, uint16_t* FAME_MEMORY_TYPE scratch, bls_point_t* FAME_MEMORY_TYPE p1, bls_point_t* FAME_MEMORY_TYPE p2) {
|
|
if (bls_point_is_zero(p1)) {
|
|
bls_point_copy(p2, p1);
|
|
return;
|
|
} else if (bls_point_is_zero(p2)) {
|
|
return;
|
|
}
|
|
|
|
uint16_t* base = scratch;
|
|
fp2_int_t* u1 = (fp2_int_t*) FAME_WALLOC(scratch, FP2_INT_WSIZE);
|
|
fp2_int_t* u2 = (fp2_int_t*) FAME_WALLOC(scratch, FP2_INT_WSIZE);
|
|
fp2_int_t* v1 = (fp2_int_t*) FAME_WALLOC(scratch, FP2_INT_WSIZE);
|
|
fp2_int_t* v2 = (fp2_int_t*) FAME_WALLOC(scratch, FP2_INT_WSIZE);
|
|
fp2_int_t* a = (fp2_int_t*) FAME_WALLOC(scratch, FP2_INT_WSIZE);
|
|
|
|
fame_fp2_mult_fp2(uptable, &p2->y, &p1->z, u1);
|
|
fame_fp2_mult_fp2(uptable, &p1->y, &p2->z, u2);
|
|
fame_fp2_mult_fp2(uptable, &p2->x, &p1->z, v1);
|
|
fame_fp2_mult_fp2(uptable, &p1->x, &p2->z, v2);
|
|
|
|
if (fp2_int_equals(v1, v2)) {
|
|
if (fp2_int_equals(u1, u2)) {
|
|
bls_point_double(uptable, base, p1);
|
|
return;
|
|
} else {
|
|
bls_point_zero(p1);
|
|
return;
|
|
}
|
|
}
|
|
|
|
fame_fp2_sub(uptable, u1, u2, u1);
|
|
fame_fp2_sub(uptable, v1, v2, v1);
|
|
fame_fp2_mult_fp2(uptable, &p1->z, &p2->z, &p1->z);
|
|
fame_fp2_square(uptable, v1, &p1->x);
|
|
|
|
fame_fp2_mult_fp2(uptable, v1, &p1->x, &p1->y);
|
|
fame_fp2_mult_fp2(uptable, v2, &p1->x, v2);
|
|
fame_fp2_add(uptable, v2, v2, &p1->x);
|
|
|
|
fame_fp2_square(uptable, u1, a);
|
|
fame_fp2_mult_fp2(uptable, a, &p1->z, a);
|
|
fame_fp2_sub(uptable, a, &p1->y, a);
|
|
fame_fp2_sub(uptable, a, &p1->x, a);
|
|
|
|
fame_fp2_mult_fp2(uptable, v1, a, &p1->x);
|
|
fame_fp2_mult_fp2(uptable, &p1->y, &p1->z, &p1->z);
|
|
|
|
fame_fp2_mult_fp2(uptable, &p1->y, u2, u2);
|
|
fame_fp2_sub(uptable, v2, a, v2);
|
|
fame_fp2_mult_fp2(uptable, u1, v2, &p1->y);
|
|
fame_fp2_sub(uptable, &p1->y, u2, &p1->y);
|
|
}
|
|
|
|
void bls_multiply(uint16_t* FAME_MEMORY_TYPE uptable, uint16_t* FAME_MEMORY_TYPE scratch, uint16_t* FAME_MEMORY_TYPE d, bls_point_t* FAME_MEMORY_TYPE p, bls_point_t* FAME_MEMORY_TYPE out) {
|
|
bls_point_t* fake = (bls_point_t*) FAME_WALLOC(scratch, BLS_POINT_WSIZE);
|
|
bls_point_zero(out);
|
|
bls_point_zero(fake);
|
|
bls_point_t* tb[] = { fake, out };
|
|
|
|
for (uint16_t i = 0; i < 255; i++) {
|
|
bls_point_add(uptable, scratch, tb[(d[0] & 1)], p);
|
|
bls_point_double(uptable, scratch, p);
|
|
|
|
gphlibSfrUm_PKCC_OPLEN.wVal = ECDSA_OP_SIZE;
|
|
fame_rshift(d, 1);
|
|
gphlibSfrUm_PKCC_OPLEN.wVal = FP2_OP_SIZE;
|
|
}
|
|
}
|
|
|
|
void bls_affine_point(uint16_t* FAME_MEMORY_TYPE uptable, bls_point_t* FAME_MEMORY_TYPE p) {
|
|
fame_fp2_invert(uptable, &p->z, &p->z);
|
|
fame_fp2_mult_fp2(uptable, &p->x, &p->z, &p->x);
|
|
fame_fp2_mult_fp2(uptable, &p->y, &p->z, &p->y);
|
|
}
|
|
|
|
void bls_toggle_montgomeryxy(uint16_t* FAME_MEMORY_TYPE uptable, bls_point_t* FAME_MEMORY_TYPE p) {
|
|
fame_fp2_do(uptable, &p->x, &p->y, &p->x, BLS_MONTGOMERY_TOGGLEXY, BLS_MONTGOMERY_TOGGLEXY_LEN);
|
|
|
|
uint16_t* rre = FAME_RPTR(uptable[9]);
|
|
uint16_t* rim = FAME_RPTR(uptable[10]);
|
|
|
|
for (uint8_t i = 0; i < FP2_OP_WSIZE; i++) {
|
|
p->y.re[i] = rre[i];
|
|
p->y.im[i] = rim[i];
|
|
}
|
|
}
|
|
|
|
uint16_t blsSign() {
|
|
uint16_t* FAME_MEMORY_TYPE sk = fameMem;
|
|
bls_point_t* FAME_MEMORY_TYPE h = (bls_point_t*) &sk[ECDSA_OP_WSIZE];
|
|
bls_point_t* FAME_MEMORY_TYPE s = (bls_point_t*) &fameMem[ECDSA_OP_WSIZE+BLS_POINT_WSIZE];
|
|
uint16_t* FAME_MEMORY_TYPE uptable = &fameMem[ECDSA_OP_WSIZE+(BLS_POINT_WSIZE*2)];
|
|
uint16_t* FAME_MEMORY_TYPE r2 = &uptable[ECDSA_OP_WSIZE];
|
|
uint16_t* FAME_MEMORY_TYPE nd = &r2[FP2_OP_WSIZE];
|
|
uint16_t* FAME_MEMORY_TYPE n = &nd[FAME_OW_SIZE];
|
|
uint16_t* FAME_MEMORY_TYPE x = &n[FP2_OP_WSIZE];
|
|
uint16_t* FAME_MEMORY_TYPE y = &x[FP2_OP_WSIZE+FAME_OW_SIZE];
|
|
uint16_t* FAME_MEMORY_TYPE t1 = &y[FP2_OP_WSIZE+FAME_OW_SIZE];
|
|
uint16_t* FAME_MEMORY_TYPE t2 = &t1[FP2_OP_WSIZE];
|
|
uint16_t* FAME_MEMORY_TYPE t3 = &t2[FP2_OP_WSIZE];
|
|
uint16_t* FAME_MEMORY_TYPE scratch = &t3[FP2_OP_WSIZE];
|
|
|
|
flipmpi((uint8_t*) sk, ECDSA_OP_SIZE);
|
|
flipmpi((uint8_t*) h->x.re, FP2_OP_SIZE);
|
|
flipmpi((uint8_t*) h->x.im, FP2_OP_SIZE);
|
|
flipmpi((uint8_t*) h->y.re, FP2_OP_SIZE);
|
|
flipmpi((uint8_t*) h->y.im, FP2_OP_SIZE);
|
|
|
|
for (uint8_t i = 0; i < FP2_OP_WSIZE; i++) {
|
|
h->z.re[i] = BLS12381_ONE[i];
|
|
h->z.im[i] = 0x0000;
|
|
r2[i] = BLS12381_R2[i];
|
|
n[i] = BLS12381_NDASH_N[i+FAME_OW_SIZE];
|
|
}
|
|
|
|
for (uint8_t i = 0; i < FAME_OW_SIZE; i++) {
|
|
nd[i] = BLS12381_NDASH_N[i];
|
|
}
|
|
|
|
uptable[4] = FAME_PTR(r2);
|
|
uptable[5] = FAME_PTR(n);
|
|
uptable[6] = FAME_PTR(x);
|
|
uptable[7] = FAME_PTR(y);
|
|
uptable[9] = FAME_PTR(t1);
|
|
uptable[10] = FAME_PTR(t2);
|
|
uptable[11] = FAME_PTR(t3);
|
|
|
|
FAME_WAIT(PHLIB_SFRUMPKCC_STATUS_GOANY_MASK);
|
|
|
|
gphlibSfrUm_PKCC_OPLEN.wVal = FP2_OP_SIZE;
|
|
gphlibSfrUm_PKCC_MCLEN.wVal = FP2_OP_SIZE;
|
|
gphlibSfrUm_PKCC_UPCTRL.bVal = PHLIB_SFRUMPKCC_UPCTRL_CACHE_EN_MASK;
|
|
gphlibSfrUm_PKCC_UPTRT.wVal = FAME_PTR(uptable);
|
|
|
|
fame_load_macros();
|
|
|
|
bls_toggle_montgomeryxy(uptable, h);
|
|
bls_multiply(uptable, scratch, sk, h, s);
|
|
bls_affine_point(uptable, s);
|
|
|
|
r2[0] = 0x0001;
|
|
for (uint8_t i = 1; i < FP2_OP_WSIZE; i++) {
|
|
r2[i] = 0x0000;
|
|
}
|
|
|
|
bls_toggle_montgomeryxy(uptable, s);
|
|
|
|
phNativeLibParameterArea_t* params = (phNativeLibParameterArea_t*)SB_INFO_STRUCT_START;
|
|
|
|
flipmpi((uint8_t*) s->x.re, FP2_OP_SIZE);
|
|
flipmpi((uint8_t*) s->x.im, FP2_OP_SIZE);
|
|
flipmpi((uint8_t*) s->y.re, FP2_OP_SIZE);
|
|
flipmpi((uint8_t*) s->y.im, FP2_OP_SIZE);
|
|
|
|
params->siCopyBackAddress = (puint8_uni_t) s;
|
|
params->siCopyBackSize = (FP2_OP_SIZE * 4);
|
|
params->scCopyBackAtomic = 0xff;
|
|
|
|
return (FP2_OP_SIZE * 4);
|
|
}
|
|
|
|
/* Main entry to test native library -> USR_0 */
|
|
LLVM_ISR_WITH_ARGS uint16_t mainEntry(uint16_t funcId) {
|
|
sil(0);
|
|
OpenResources_SYS(NATIVELIB_OPEN_FAME_MASK|NATIVELIB_OPEN_RNG_MASK);
|
|
fame_open();
|
|
|
|
switch (funcId) {
|
|
case SB_BLS: return blsSign();
|
|
case SB_ECDSA: return ecdsaSign();
|
|
}
|
|
|
|
fame_close();
|
|
CloseResources_SYS(NATIVELIB_OPEN_FAME_MASK|NATIVELIB_OPEN_RNG_MASK);
|
|
|
|
return 0x6d00;
|
|
}
|
|
|
|
/* FAME UPFIFO Empty ISR */
|
|
void phIntHandler_FAME3_UPFIFO_Empty_Isr() LLVM_ISR {
|
|
while(!(gphlibSfrUm_PKCC_UPIRQ.bVal & PHLIB_SFRUMPKCC_UPIRQ_STOP_READING_MASK)) {
|
|
gphlibSfrUm_PKCC_UPFIFO.wVal = *(fup++);
|
|
gphlibSfrUm_PKCC_UPFIFO.wVal = *(fup++);
|
|
gphlibSfrUm_PKCC_UPFIFO.wVal = *(fup++);
|
|
}
|
|
|
|
uint8_t mask;
|
|
|
|
if (gphlibSfrUm_PKCC_UPLEN.bVal) {
|
|
mask = PHLIB_SFRUMPKCC_UPIRQ_IRQ_MASK;
|
|
} else {
|
|
mask = PHLIB_SFRUMPKCC_UPIRQ_IRQ_MASK | PHLIB_SFRUMPKCC_UPIRQ_LVL_MASK_VALUE_HIGH;
|
|
}
|
|
|
|
gphlibSfrUm_PKCC_UPIRQ.bVal = (gphlibSfrUm_PKCC_UPIRQ.bVal & ~mask) | PHLIB_SFRUMPKCC_UPIRQ_CLR_MASK;
|
|
}
|
|
|
|
/* Timer ISR */
|
|
void phIntHandler_TimerA_Isr(void) LLVM_ISR {
|
|
}
|
|
|
|
/* Reset ISR */
|
|
LLVM_ISR_WITH_ARGS void phappSysCall_Reset_POR() {
|
|
|
|
}
|
|
|
|
/* Exception ISR */
|
|
LLVM_ISR_WITH_ARGS void phSecureBox_Exception_UsrCall(uint16_t liExceptionType, uint16_t liExceptionReason) {
|
|
Exception_SYS(liExceptionType, liExceptionReason);
|
|
}
|
|
|