Skip to content

Instantly share code, notes, and snippets.

@drdnar
Last active June 29, 2021 21:48
Show Gist options
  • Save drdnar/39f0e3eec3312bf76c2d2a58a07c655f to your computer and use it in GitHub Desktop.
Save drdnar/39f0e3eec3312bf76c2d2a58a07c655f to your computer and use it in GitHub Desktop.
eZ80 constant-time compare function
; bool CompareDigest(uint8_t* buffer1, uint8_t* buffer2, size_t count);
; This optimized implementation is guaranteed to run in constant time for any given specific count.
; It's untested but it looks right to me.
hashlib_CompareDigest:
call ti._frameset0
ld iy, (ix + 6)
ld de, (ix + 12)
ld ix, (ix + 9)
; BC is constant zero
; DE is number of bytes to compare
; HL is number of different bytes
; IY is read pointer 1
; IX is read pointer 2
xor a, a ; Carry flag is reset by __frameset0 but added to prevent stabbing by MateoC
sbc hl, hl
push hl
pop bc
hashlib_CompareDigest_loop:
ld a, (iy)
sub a, (ix)
; Now set carry flag iff A == 0
add a, $ff
; Add carry flag to HL
adc hl, bc
; Update loop
inc ix
inc iy
dec de
; Check if DE is zero by comparing it with BC
ex de, hl
sbc hl, bc ; Carry flag must be reset by above ADC unless you asked to compare 16777216 bytes
ex de, hl
jr nz, hashlib_CompareDigest_loop
; Convert HL to 0 or 1
dec bc ; BC = $FFFFFF
xor a, a
; Set carry flag unless HL is zero
add hl, bc
adc a, a
pop ix
ret
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment