def store_load_right_to_left(reg): AVR.POPZ() # idx + 48 AVR.STZ32(reg[5]) # store z AVR.STZ32(reg[2]) # store y AVR.SBIW(30, 8) AVR.STZ32(reg[4]) # store x AVR.STZ32(reg[1]) # store z AVR.SBIW(30, 8) AVR.STZ32(reg[3]) # store y AVR.STZ32(reg[0]) # store x reg = init_state() # reinit the state. # current idx is +8 AVR.ADIW(30, 8) # go to idx + 16 AVR.LDZ32(reg[1]) # load r[1] AVR.LDZ32(reg[4]) # load r[2] AVR.ADIW(30, 8) # skip the next 4 words as they contain garbage (former r[3]) AVR.LDZ32(reg[2]) # load r[4] AVR.LDZ32(reg[5]) # load r[5] # pop the initial values of the other half from the stack ! :p AVR.POP32(reg[0]) # load r[0] AVR.POP32(reg[3]) # load r[1] # current value of idx is +40 AVR.PUSHZ() return reg
def load(): # load the first column # load x then y then z reg = init_state() AVR.LDZ32(reg[0]) AVR.LDZ32(reg[3]) AVR.ADIW(30,8) AVR.LDZ32(reg[1]) AVR.LDZ32(reg[4]) AVR.ADIW(30,8) AVR.LDZ32(reg[2]) AVR.LDZ32(reg[5])
def load(reg): # load the first column # load x then y then z reg = init_state() AVR.LDZ32(reg[0]) AVR.LDZ32(reg[3]) AVR.ADIW(30, 8) AVR.LDZ32(reg[1]) AVR.LDZ32(reg[4]) AVR.ADIW(30, 8) AVR.LDZ32(reg[2]) AVR.LDZ32(reg[5]) AVR.PUSHZ() # save current pointer (point to the first half of the state) return reg
def stack_load_left_to_right(reg): AVR.POPZ() # idx + 48 AVR.PUSH32(reg[3]) AVR.PUSH32(reg[0]) # DO WE DO ONLY A SIMPLE REINIT OR A FULL ??? reg[0].sort() # we only re init the values in r[0] and r[3] reg[3].sort() # we only re init the values in r[0] and r[3] AVR.SBIW(30, 48) # go the begining of the state AVR.LDZ32(reg[0]) # load r[0] AVR.LDZ32(reg[3]) # load r[3] AVR.ADIW(30, 40) # go back to idx+48 : 4 + 4 + 16 + 16 AVR.PUSHZ() # push to the stack : idx + 48 return reg
def stack_load_right_to_left(reg): AVR.POPZ() # idx + 40 AVR.PUSH32(reg[3]) AVR.PUSH32(reg[0]) reg[3].sort() reg[0].sort() # reg = reinit_state(reg) # we only re init the values in r[0] and r[3] AVR.SBIW(30, 32) # skip the next two words AVR.LDZ32(reg[0]) # load r[0] AVR.LDZ32(reg[3]) # load r[3] AVR.ADIW(30, 24) # skip back 8 + 16 # current value of idx is +40 AVR.PUSHZ() return reg
AVR.comment(' */') AVR.comment( ' X,Y,Z: Indirect Address Register (X=R27:R26, Y=R29:R28, and Z=R31:R30)') AVR.push_to_stack() AVR.comment('START CYCLE COUNT') constants = [0x9e377900 ^ (24 - 4 * x) for x in range(6)] AVR.MOVW(30, 24) # load operand address state to Z registers = init_state() registers = load(registers) registers = first_3SPboxes(registers, constants[0]) # rounds 1 2 3 - left registers = store(registers) AVR.ADIW(30, 8) registers = load(registers) registers = first_3SPboxes(registers, 0) # rounds 1 2 3 - right AVR.comment('last half is active, we did 3 rounds') # idx = 24 # to minimize load and store, we push the current r[0] and r[3] to the stack # load from the memory r[0] r[3] this is the big swap registers = stack_load_left_to_right(registers) # idx = 48 registers = half_state_4SPbox(registers, 0) # rounds 4 5 6 7 - right # idx = 24 registers = store_load_right_to_left(registers)