calculation of the xor values from the seed:

float a = seed/1000.0
for(int i=1;i<0x400;i++)
{
   float b = int(a/127773)
   float c = a - b*127773
   a = c*16807 - b*2836
   if a<0: a+=2147483647
   xor_buf[i] = int(a/2147483647*256)&0xFF
}

calculation of the user seed from the string ID
  
  t1 = 1;
  sum = 0;
  i = 0;
  do
  {
    t1 = (t1 + id[i++]) % 0xFFF1;
    sum = (t1 + sum) % 0xFFF1;
  }
  while ( i <0x80 );
  user_seed = (sum<<16) | t1;

decryption:
  xor_val = xor_buf[file_offset%0x400]
  val_out = val_in^xor_val
  if (val_out==0x1A) 
    val_out = val_in

embiid file:

  0   4  file_seed         seed to decrypt the header
  4   5  id<file_seed>     encrypted with file_seed. 'Valid': non-personalized(ubk); 'EBook': personalized (text is encrypted with user seed)
  9   4  cover_off         offset of cover image
  D   4  cover_len         length of cover image (jpeg)
 11   1  ?
 12  32  title<file_seed>  book title (space-padded)
 44 3BA  author<file_seed> book author (space-padded)
3FE   2  nch               chapter count
400 4*<nch>                chapter lengths
800   x                    chapter texts. encrypted with file_seed for ubk and user_seed for ebk

