ECC_part1 - Guessing k one bit at a time

From this python block:

It is quite easy for one to see that the our first guess (guess[0]) corresponds to the Most Significant Bit of the k we set earlier and we try to recover. However when I look back to our capture function “get_traces(N=50)” the target.capture_trace() method writes the key and X,Y coordinates in little-endian fashion as seen in (


If this is the case then why our first guess is related with the Most significant bit and not the Least Significant one, as it is essentially originating from trace.wave[] (
Due to this block:

). Since we used little-endianess should the first-subtrace of the len(cycle) trace be somewhat correlated with the Least Significant Bit?
Thank you in advance!

Hi Antonios,

Endianess is… definitely not my favorite element of programming! :wink:
In this particular case I don’t remember the details but I can assure you that the bit order is as described in the notebook. There are several places between the Python call and the target Verilog code where byte order can be swapped around. The nice thing about cryptography is that if you get something like endianess wrong, the results will be obviously wrong. You can see in that the results are checked against ecpy, to be extra sure.


1 Like

Hello, there Jean-Piere (@jpthibault). In the first place I am grateful for your quick response.
Since I am familiar with verilog and simulations after diving deep in the ECC_part1 tutorial, I would like to make the following observations (please correct me if any of those are unsubstantiated):

  1. Obviously the K_din 32-bit registers holds 4 sub-bytes at a time of the scalar k we trying to attack/recover.

  2. I noticed by carefully examining the simulation waveform, that all the subsequent values of the K_din are assigned to the move_inhibit wire. For example let k = 0x70a12c2db16845ed56ff68cfc21a472b3f04d7d6851bf6349f2d7d5b3452b38a, for the first 4 Most Significant bytes(70a12c2d == 32’b01110000101000010010110000101101) move_inhibit(dependent on k_din_reg[31]) will inherit these bit values from left to right during the process of the corresponding bit(bit0 = 0, bit1 =1, bit2 =1, … ,bit30=0, bit31=1). It’s like the move_inhibit having a double-meaning aside from it’s role to the add multiplication.

  3. (This one is more of question than an observation) As explicitly stated in the comments of notebook "The x/y/z writes happen simultaneously (at cycle rupdate_offset), but the three coordinates are read at three different times (r[x|y|z]read_offset).
    The correlation is computed over rupdate_cycles = 8 clock cycles, because that’s how many clock cycles it takes to read or write an intermediate R_x, R_y or R_z value (256-bit values into 32-bit wide memories)".
    Are the 256bit-values written to and read from the BRAM-alike the x,y,z ECC coordinates being calculated for the intermediate results?

  4. Obviously the only thing we care about is the correlation between the writes and reads, by knowing exactly when the two operations are happening in terms of clock cycles. The latter will allows us to define a “clear” threshold to determine the value of the move_inhibit for each one of the 256-bits, implicitly giving us access to the K_din values(if observation 2 is valid), ultimately leading to the successful k-scalar recovery.

(Setup: CW-Lite with CW305 35t )

Yes, you have the correct understanding;

2- the way I look at it, there is no double meaning: move_inhibit does just what it says, by using the current bit of k directly. But this is probably just semantics / choice of words, I think you have the correct understanding.

3- tbh I never verified this, but I would assume that to be the case.


1 Like